I would probably go in the direction of 3 tables to start. Those would be: activity, activity settings , activity global settings. The activity table would store all the individual activities. The activity settings table would store all the unique settings for an individual activity. The activity global settings table would store all the settings that are applied to each activity. So something like this to start:
activity
- id (primary key)
- title (human readable name of activity)
- description (description of activity)
activity_setting
- id (primary key)
- activity_id (foreign key to activity that setting belongs to)
- title (human readable name of setting)
- required (boolean used to determine whether setting is required)
- default_value (default value if applicable for unspecified setting)
activity_global_setting
- id (primary key)
- title (human readable name of global setting such as; parents name or child name)
- required (boolean used to determine whether setting is required)
- default_value (default value if applicable for unspecified setting)
In regards to the front end this would be enough to:
1.) create a list of activities for users to pick (create)
2.) Once an activity is chosen present user with configurable settings for the activity (global and instance specific)
Now once that is in place the question of how to store the data when a user creates an activity can resolved. In regards to that I would probably go with three three tables. Those tables being: activity_instance, activity_setting_instance, activity_global_setting_instance. The activity instance table would store any generic information for an individual activity that is shared by all activities. The activity_setting_instance table would store the specific configuration values for an activity created by a user. The activity_global_setting_instance table would store global configuration values for a single instance of an activity. With that the schema could look something like this:
activity_instance
- id (primary key)
- activity_id (foreign key to the activity that row represents)
- user_id (foreign key to the user within the system that created the instance of the activity if applicable)
activity_setting_instance
- id (primary key)
- activity_instance_id (foreign key to activity_instance for which setting belongs)
- activity_setting_id ( foreign key to activity_setting for which setting defines)
- setting_value (the configurable value specified by the user for the setting)
activity_global_setting_instance
- id (primary key)
- activity_instance_id (foreign key to activity_instance for which global setting belongs)
- activity_global_setting_id (foreign key to activity_global_setting for which setting defines)
- setting_value (the configurable value specified by the user for the global setting)
Now one of issues that has not been addressed here is the representation of form fields for settings. In the case above it would be assumed that ALL settings instance specific or otherwise will be represented with a text field. Supporting selects, radios, check boxes opens up all whole other can of worms. Furthermore, there is no support for multiple values for a single setting. Lastly, there is no means of validating a single setting. Each on of those features mentioned would require more work and thought in regards to settings schema. So much so that while I did not do not use a parent child table schema for settings of global and instance specific it would be worth considering. Though depending on what global settings exist it may be best to make those columns in the activity_instance table. In theory the parent name and child name could be columns there.
Though that starts to bring up another point. While I have very little knowledge of the business goal of the application it seems like one would register than should specify their children. The “parent” would really be nothing more than the user and the child would than be a foreign key or maybe relation table depending on whether an individual activity can be assigned to more than a single child. These are all things that good to anticipate ahead of time considering they would drastically change the correct approach considering using “virtual” foreign key is bad practice. Though beyond that having a parent specific their children ahead of time would make it possible to use a foreign key a reduce replicate, none normalized data.
So if you were to have users (parents) specify children ahead of time or proceed with a look up upon activity creation for a parents children I would modify the schema as follows.
user_children
- id (primary key)
- user_id (foreign key to the user who represents the parent of the children)
- first_name
- last_name
- middle_name
modify the activity_instance table as follows. Though the restriction here is that an activity instance can only have a single parent and child associated with it. If you needed to support assigning multiple children or parents a relation table would be needed instead.
activity_instance
- id (primary key)
- activity_id (foreign key to the activity that row represents)
- user_id (foreign key to the user within the system that created the instance of the activity if applicable)
- child_id (foreign key to child that activity belongs to)
I did leave some of details out here considering the schema designs shown here are really only meant to show relations and required data. The end tables may have other columns but the bare bones of a business logic are supported with what has been provided. Also, the data types have not been defined considering that is an implementation detail and everything provided is only meant to show a concept/rough of applicable tables.
A warning here I think is warranted. The business requirements seem to require getting really close to a meta relational data base. In that each activity has "unknown"settings which can be referred as attributes. The second you need to start supporting anything other than a simple text value for settings many bad things will probably start occur without rethinking / refactoring attributes into separate tables which can support other values such as; true integers, foreign keys, dates, etc. Storing everything as as text regardless of actual data type is really hacky though some what necessary when the settings are unknown or user is able to create them on the fly. It can become a delicate balance between practicality and idealism.