The application now uses a database-backed form configuration system with versioning support. Form templates are stored in the form_config table instead of being read directly from JSON files.
CREATE TABLE form_config (
id SERIAL PRIMARY KEY,
template_json JSONB NOT NULL,
year INTEGER NOT NULL,
version INTEGER NOT NULL,
is_active BOOLEAN NOT NULL DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(year, version)
);Fields:
template_json: The complete form configuration in JSON formatyear: The academic year for this form (e.g., 2025)version: Version number for this year (starts at 1, increments for each new version)is_active: Only one form per year can be active at a timecreated_at: When this version was createdupdated_at: When this version was last modified
- Queries the database for active form configuration:
FormConfig.query.filter_by(is_active=True).order_by(FormConfig.year.desc(), FormConfig.version.desc()).first() - Returns the
template_jsonif found - Falls back to reading from
markdown/dynamic_form_json.jsonif no active form exists in database
- On component mount, calls
api.getForm()to fetch the form configuration - Displays a loading spinner while fetching
- Renders the form using the fetched configuration
- Shows error message if fetch fails
When you need to update the form (e.g., add new fields, change validation):
-
Use the seed script:
cd backend source .venv/bin/activate python seed_form.py
-
The script will:
- Check if an active form exists for the year
- Prompt you to create a new version
- Deactivate the old version
- Create and activate the new version
-
Manual version creation:
from app import create_app from models import db, FormConfig app = create_app() with app.app_context(): # Deactivate all existing forms for 2025 FormConfig.query.filter_by(year=2025, is_active=True).update({'is_active': False}) # Create new version new_form = FormConfig( template_json=your_json_data, year=2025, version=2, # Next version number is_active=True ) db.session.add(new_form) db.session.commit()
# Get all versions for a specific year
versions = FormConfig.query.filter_by(year=2025).order_by(FormConfig.version.desc()).all()
for v in versions:
print(f"Version {v.version} - Active: {v.is_active} - Created: {v.created_at}")from app import create_app
from models import db, FormConfig
app = create_app()
with app.app_context():
# Deactivate current version
FormConfig.query.filter_by(year=2025, is_active=True).update({'is_active': False})
# Activate version 1
old_version = FormConfig.query.filter_by(year=2025, version=1).first()
old_version.is_active = True
db.session.commit()The seed_form.py script loads the form configuration from markdown/dynamic_form_json.json into the database.
cd backend
source .venv/bin/activate
python seed_form.pyFeatures:
- Automatically detects the year from the JSON title
- Checks for existing active forms
- Prompts before creating new versions
- Handles version incrementing
- Deactivates old versions when creating new ones
The JSON file must have this structure:
{
"title": "VGLUG APPLICATION FORM 2025",
"sections": {
"section_key": {
"label": "Section Label",
"fields": [
{
"label": "Field Label",
"actual_name": "field_name",
"type": "text",
"mandatory": true
}
]
}
}
}- Created
FormConfigmodel in backend/models.py - Updated
/formendpoint in backend/app.py to query database - Modified frontend/src/App.tsx to fetch form from API
- Created seed script backend/seed_form.py
- Version Control: Keep track of all form changes over time
- Easy Rollback: Revert to previous versions if needed
- No Deployment Required: Update forms without redeploying code
- Audit Trail: Track when forms were created and modified
- Year-based Organization: Manage different forms for different academic years
Returns the active form configuration.
Response:
{
"title": "VGLUG APPLICATION FORM 2025",
"sections": { ... }
}Status Codes:
200: Success500: Error loading form (falls back to file, returns error if file also fails)
Possible improvements:
- Admin dashboard to manage form versions
- Form preview before activation
- Export/import form configurations
- Form analytics (which fields are most commonly left blank, etc.)
- Draft versions (not yet active)
- Scheduled activation of forms