Architect-prompti parannettu, relaatiotuki templateihin, englanti-sääntö
- SPEC_SYSTEM: chain-of-thought, domain-esimerkit, anti-patternit, relaatiosäännöt - Speksi-puhdistus: korjaa sa_type | None -virheet automaattisesti - Etusivun teksti päivitetty - Koodissa käytetään aina englantia (entity/field names)
This commit is contained in:
@@ -1121,33 +1121,38 @@ OUTPUT FORMAT:
|
|||||||
|
|
||||||
// === Template Pipeline — rakennuspalaset ===
|
// === Template Pipeline — rakennuspalaset ===
|
||||||
|
|
||||||
const SPEC_SYSTEM = `You are a software architect. Given a project description, output a JSON specification.
|
const SPEC_SYSTEM = `You are a software architect who designs database schemas for Python web applications.
|
||||||
Output ONLY valid JSON, no explanations. Follow this exact schema:
|
|
||||||
{
|
THINK STEP BY STEP before outputting JSON:
|
||||||
"project_name": "short-name",
|
1. What are the main ENTITIES (nouns) in this project?
|
||||||
"description": "One sentence",
|
2. What FIELDS does each entity need? (name, type, required?)
|
||||||
"entities": [
|
3. Which entities REFERENCE each other? (e.g. "a Book belongs to an Author" → Book has author_id)
|
||||||
{
|
4. Are there Date/DateTime fields? → add extra_imports
|
||||||
"name": "Todo",
|
|
||||||
"table_name": "todos",
|
Then output ONLY valid JSON (no explanations before or after).
|
||||||
"fields": [
|
|
||||||
{"name": "title", "sa_type": "String(255)", "py_type": "str", "nullable": false, "default": null},
|
SCHEMA:
|
||||||
{"name": "description", "sa_type": "Text", "py_type": "str | None", "nullable": true, "default": null},
|
{"project_name":"short-name","description":"One sentence","entities":[{"name":"EntityName","table_name":"entity_names","fields":[{"name":"field_name","sa_type":"String(255)","py_type":"str","nullable":false,"default":null}]}],"relationships":[{"from":"ChildEntity","field":"parent_id","to":"ParentEntity","type":"many-to-one"}],"extra_imports":[]}
|
||||||
{"name": "status", "sa_type": "String(20)", "py_type": "str", "nullable": false, "default": "pending"}
|
|
||||||
]
|
FIELD RULES:
|
||||||
}
|
- sa_type: String(N), Text, Integer, Date, DateTime, Boolean, Float
|
||||||
],
|
- py_type: str, int, float, bool, date, datetime — append " | None" if nullable
|
||||||
"extra_imports": ["from datetime import date"]
|
- Status fields: use String(20) with default value, NEVER Enum
|
||||||
}
|
- Every entity gets "id" automatically — do NOT add id or redundant ID fields
|
||||||
RULES:
|
- Use snake_case for field names
|
||||||
- sa_type: SQLAlchemy column type (String(N), Text, Integer, Date, DateTime, Boolean, Float)
|
|
||||||
- py_type: Python type hint (str, int, float, bool, date, datetime, str | None, etc.)
|
RELATIONSHIP RULES:
|
||||||
- Do NOT use Enum — use String(20) with a default value for status fields
|
- If entity A "belongs to" entity B → A has b_id field (Integer, nullable=false) + relationship entry
|
||||||
- nullable: true = optional field
|
- EVERY _id field MUST have a matching relationship entry
|
||||||
- default: null = no default, otherwise a string/number value
|
- Parent entities must appear BEFORE children in the entities array
|
||||||
- extra_imports: stdlib imports needed in schemas.py (e.g. "from datetime import date")
|
- If no relationships, set "relationships": []
|
||||||
- entity name: PascalCase singular, table_name: snake_case plural
|
|
||||||
- Keep it simple: 1-3 entities, 3-7 fields each`;
|
AVOID: redundant ID fields, generic names, more than 7 fields or 3 entities, non-English entity/field names (ALWAYS English even if description is Finnish)
|
||||||
|
|
||||||
|
EXAMPLES (adapt, don't copy):
|
||||||
|
Todo app → Todo: title(str), description(Text|None), due_date(Date|None), status(String20="pending")
|
||||||
|
E-commerce → Customer: name,email / Product: name,price(Float),stock(Int) / Order: customer_id→Customer, product_id→Product, quantity(Int), order_date(Date)
|
||||||
|
Blog → Author: name,email,bio(Text|None) / Post: title, content(Text), author_id→Author, published_at(DateTime|None), status(String20="draft")`;
|
||||||
|
|
||||||
function extractJson(text) {
|
function extractJson(text) {
|
||||||
const m = text.match(/```(?:json)?\s*\n([\s\S]*?)```/);
|
const m = text.match(/```(?:json)?\s*\n([\s\S]*?)```/);
|
||||||
|
|||||||
@@ -17,17 +17,20 @@ body {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: var(--bg);
|
background: var(--bg);
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
height: 100vh;
|
min-height: 100vh;
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 1600px;
|
max-width: 1600px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px 40px;
|
padding: 20px 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app.container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
#app:not(.active) { display: none; }
|
#app:not(.active) { display: none; }
|
||||||
@@ -44,7 +47,7 @@ body {
|
|||||||
|
|
||||||
/* Panels */
|
/* Panels */
|
||||||
.panel { display: none; }
|
.panel { display: none; }
|
||||||
.panel.active { display: flex; flex-direction: column; flex: 1; min-height: 0; }
|
.panel.active { display: flex; flex-direction: column; flex: 1; min-height: 0; overflow-y: auto; }
|
||||||
|
|
||||||
/* Status bar */
|
/* Status bar */
|
||||||
.status-bar {
|
.status-bar {
|
||||||
|
|||||||
Reference in New Issue
Block a user