Template System
If you design templates properly, you unlock:
- Multiple standards later
- Org-specific templates
- Versioned standards
- Reset / diff features
- Future compliance insights
Let’s design this cleanly and professionally.
Goal
Design a template system that:
- Seeds ISO-like sections
- Is extensible
- Is versionable
- Is simple in v0.1
- Doesn’t pollute your DB
Key Principle
Templates are configuration, not data.
They should:
- Live outside the database
- Be immutable
- Be versioned with your code
- Be loaded via a registry
Recommended Folder Structure
Inside your Next.js app:
/src
/templates
/standards
iso-29148.v1.json
index.ts
loader.tsKeep it simple.
Template File Structure (Clean & Extensible)
Let’s define a professional but minimal JSON structure. Note: example for v1:
{
"id": "iso-29148",
"version": "1.0.0",
"label": "ISO/IEC/IEEE 29148:2018",
"description": "Recommended structure for Software Requirements Specifications.",
"sections": [
{
"code": "1",
"title": "Introduction",
"hint": "Provide an overview of the entire document.",
"required": true
},
{
"code": "1.1",
"title": "Purpose",
"hint": "Describe the purpose of the system.",
"required": true
},
{
"code": "1.2",
"title": "Scope",
"hint": "Define system boundaries and objectives.",
"required": true
},
{
"code": "2",
"title": "Overall Description",
"required": true
},
{
"code": "3",
"title": "Specific Requirements",
"required": true
},
{
"code": "3.1",
"title": "Functional Requirements",
"recommendedFor": "FUNCTIONAL"
},
{
"code": "3.2",
"title": "Non-Functional Requirements",
"recommendedFor": "NON_FUNCTIONAL"
}
]
}Why This Structure Works
| Field | Why |
|---|---|
| id | Used internally |
| version | Allows future template updates |
| label | Shown in UI |
| description | Helps onboarding |
| sections | Seeding |
| hint | UX guidance |
| required | Later compliance checks |
| recommendedFor | Intelligent UX features later |
You’re building foundation for serious evolution.
TypeScript Type Definition (Very Important)
Create a shared type.
export type SectionTemplate = {
code: string
title: string
hint?: string
required?: boolean
recommendedFor?: string
}
export type StandardTemplate = {
id: string
version: string
label: string
description?: string
sections: SectionTemplate[]
}Never trust raw JSON without typing.
Template Registry Pattern
Instead of reading arbitrary files, create a controlled registry.
index.ts
import iso29148 from "./standards/iso-29148.v1.json"
import { StandardTemplate } from "./types"
export const STANDARD_REGISTRY: Record<string, StandardTemplate> = {
"iso-29148": iso29148
}Why Registry > File Lookup
File scanning:
- unpredictable
- hard to type
- messy in production
Registry:
- explicit
- typed
- controlled
- safe
Loader Service
Create a small loader abstraction.
import { STANDARD_REGISTRY } from "./index"
import { StandardTemplate } from "./types"
export function loadStandardTemplate(id: string): StandardTemplate {
const template = STANDARD_REGISTRY[id]
if (!template) {
throw new Error(`Standard template "${id}" not found.`)
}
return template
}Keep it boring. Boring is reliable.
Seeding Integration
Your workspace creation flow:
const template = loadStandardTemplate(input.standard)
await seedSections(tx, workspaceId, template.sections)That’s it.
Smart Enhancements (v0.2+)
Because your structure supports it, later you can:
1. Template Version Tracking in Workspace
Add to Workspace:
standardId String
standardVersion StringStore:
iso-29148
1.0.0This enables:
- Template upgrades
- Compliance comparison
- Reset suggestions
2. Template Diffing
Compare:
workspace sections vs template sectionsYou can later show:
“2 recommended sections are missing.”
No refactor required.
3. Organization Templates
Later:
/templates/organizations/chalvien-v1.jsonJust register it.
No DB change needed.
What NOT To Do
- Don’t store template sections in DB
- Don’t auto-sync template changes
- Don’t hardcode section creation logic in service
- Don’t over-abstract with plugin systems yet
Design Philosophy Behind This
Templates are:
- Authoritative starting points
- Not living constraints
- Not enforced contracts
Your app:
- encourages good structure
- doesn’t punish deviation
That’s mature product thinking.
Bonus: Intelligent Future Hook
Because sections include recommendedFor, later you can:
When user creates a FUNCTIONAL requirement:
→ Suggest section 3.1 automatically.
That’s subtle intelligence.