# Prompt Generator Module

> ArchiTools internal reference -- template-driven, parameterized, provider-agnostic prompt builder.

---

## Purpose

The Prompt Generator is a structured prompt composition tool for architecture, legal, technical, GIS, rendering, BIM, compliance, and administrative workflows. It replaces ad-hoc prompt writing with a template-driven system where prompts are assembled from typed variables, ordered blocks, conditional logic, and provider-specific formatting.

The module serves users who interact with AI systems (ChatGPT, Claude, Midjourney, Copilot, domain-specific models) as part of their professional work but lack the time or inclination to engineer prompts from scratch every time.

**What it is:**
- A prompt authoring and composition engine.
- A template library organized by professional domain.
- A provider-agnostic output formatter.
- A prompt version history and favorites system.

**What it is not:**
- An AI chat interface (that is the AI Chat module).
- An API proxy to AI providers.
- A prompt execution runtime.

---

## Core Concepts

### Template

A reusable prompt blueprint. Contains a sequence of blocks with variable placeholders, metadata (domain, category, target AI type), and optional safety blocks. Templates are the primary unit of reuse.

### Block

A composable section of a prompt. Each block has a type (role, context, task, constraints, format, etc.), content with `{{variable}}` placeholders, and ordering/visibility rules. Blocks are assembled sequentially by the composition engine.

### Variable

A typed input slot that gets injected into blocks at composition time. Variables have types (text, select, boolean, tag-selector, etc.), validation rules, and Romanian UI labels. The user fills variables via an auto-generated form.

### Domain Pack

A grouped bundle of templates for a specific professional domain (architecture visualization, legal review, urbanism/GIS, etc.). Domain packs provide curated starting points so users do not need to browse the full template catalog.

### Provider Profile

Output formatting rules for a specific AI system. Controls max length, verbosity, instruction style (direct vs. conversational vs. system-prompt), and formatting preference (markdown, plain, structured). The same template produces different output for different providers.

---

## Template Schema

```typescript
interface PromptTemplate {
  id: string;
  name: string;
  category: PromptCategory;
  domain: PromptDomain;
  description: string;
  targetAiType: 'text' | 'image' | 'code' | 'review' | 'rewrite';
  blocks: PromptBlock[];
  variables: PromptVariable[];
  outputMode: OutputMode;
  providerProfile?: string;
  safetyBlocks?: SafetyBlock[];
  tags: string[];
  version: string;
  author: string;
  visibility: Visibility;
  exampleOutputs?: string[];
  metadata?: Record<string, unknown>;
}

type PromptCategory =
  | 'architecture'
  | 'legal'
  | 'technical'
  | 'administrative'
  | 'gis'
  | 'bim'
  | 'rendering'
  | 'procurement'
  | 'general';

type PromptDomain =
  | 'architecture-visualization'
  | 'technical-documentation'
  | 'legal-review'
  | 'urbanism-gis'
  | 'bim-coordination'
  | 'procurement-bidding'
  | 'administrative-writing'
  | 'general';

type OutputMode =
  | 'short'
  | 'expanded-expert'
  | 'step-by-step'
  | 'chain-of-thought'
  | 'structured-json'
  | 'checklist';

type Visibility = 'all' | 'admin' | 'internal';
```

### Field Reference

| Field | Required | Description |
|---|---|---|
| `id` | Yes | Unique identifier. Format: `kebab-case`, e.g., `legal-contract-review`. |
| `name` | Yes | Romanian display name shown in template selectors. |
| `category` | Yes | Top-level grouping for navigation and filtering. |
| `domain` | Yes | Professional domain. Maps to a domain pack. |
| `description` | Yes | Romanian description of what the template produces. |
| `targetAiType` | Yes | What kind of AI output the prompt targets. |
| `blocks` | Yes | Ordered list of prompt blocks. At least one required block must exist. |
| `variables` | Yes | Variables referenced by blocks. Can be empty if template has no dynamic content. |
| `outputMode` | Yes | Default output structure. User can override in advanced mode. |
| `providerProfile` | No | Default provider profile ID. User can override. |
| `safetyBlocks` | No | Optional safety/compliance blocks appended to the prompt. |
| `tags` | Yes | Searchable tags (reuses the platform tagging system). |
| `version` | Yes | Semver string. Incremented when template content changes. |
| `author` | Yes | Creator identifier (user ID or name). |
| `visibility` | Yes | Access level. |
| `exampleOutputs` | No | Sample outputs for preview. Helps users understand what the template produces. |
| `metadata` | No | Extensible key-value store for domain-specific metadata. |

---

## Block System

### PromptBlock Interface

```typescript
interface PromptBlock {
  id: string;
  type: BlockType;
  label: string;             // Romanian UI label
  content: string;           // template string with {{variable}} placeholders
  order: number;
  required: boolean;
  conditional?: {
    variableId: string;
    operator: 'equals' | 'notEquals' | 'truthy' | 'falsy';
    value?: string;
  };
}

type BlockType =
  | 'role'
  | 'context'
  | 'task'
  | 'constraints'
  | 'format'
  | 'checklist'
  | 'validation'
  | 'output-schema'
  | 'custom';
```

### Block Types

| Type | Purpose | Typical Position |
|---|---|---|
| `role` | Defines the AI's persona, expertise, and perspective. | First |
| `context` | Provides background information, project details, domain context. | Second |
| `task` | The core instruction -- what the AI should do. | Third |
| `constraints` | Limitations, exclusions, things to avoid. | After task |
| `format` | Output format requirements (bullet list, table, structured sections). | After constraints |
| `checklist` | Itemized list of points the output must cover. | After format |
| `validation` | Criteria for self-checking the output quality. | Near end |
| `output-schema` | JSON schema or structured format definition for the expected output. | Last |
| `custom` | Free-form block for domain-specific content that does not fit other types. | Any position |

### Conditional Blocks

A block with a `conditional` property is only included in the output if the condition evaluates to true. This allows templates to adapt based on user input without requiring separate templates.

```typescript
// Example: include a "Normative References" block only if the user selects regulatory mode
{
  id: 'block-normative-refs',
  type: 'constraints',
  label: 'Referinte normative',
  content: 'Citeaza toate referintele normative aplicabile conform {{regulation_set}}. Utilizeaza formatarea standard de citare legislativa romaneasca.',
  order: 4,
  required: false,
  conditional: {
    variableId: 'include_regulations',
    operator: 'truthy',
  },
}
```

### Block Ordering

The `order` field determines the sequence of blocks in the final prompt. Blocks are sorted ascending by `order`. Gaps in numbering are allowed and encouraged (use increments of 10) to allow inserting blocks between existing ones.

---

## Variable System

### PromptVariable Interface

```typescript
interface PromptVariable {
  id: string;
  label: string;             // Romanian UI label
  type: VariableType;
  required: boolean;
  defaultValue?: unknown;
  placeholder?: string;
  helperText?: string;       // Romanian helper text shown below the input
  options?: SelectOption[];   // for select/multi-select types
  validation?: {
    min?: number;
    max?: number;
    pattern?: string;
  };
}

type VariableType =
  | 'text'
  | 'number'
  | 'select'
  | 'multi-select'
  | 'boolean'
  | 'tag-selector'
  | 'project-selector'
  | 'company-selector'
  | 'tone-selector'
  | 'regulation-set-selector';

interface SelectOption {
  value: string;
  label: string;             // Romanian
}
```

### Variable Types

| Type | UI Control | Value Type | Notes |
|---|---|---|---|
| `text` | Text input or textarea | `string` | `validation.max` controls max character length. |
| `number` | Number input | `number` | `validation.min` / `validation.max` for range. |
| `select` | Dropdown | `string` | Single selection from `options`. |
| `multi-select` | Multi-select / checkbox group | `string[]` | Multiple selections from `options`. |
| `boolean` | Toggle / checkbox | `boolean` | Drives conditional blocks via truthy/falsy. |
| `tag-selector` | Tag picker component | `string[]` | Integrates with the platform tagging system. |
| `project-selector` | Project dropdown | `string` | Pulls from a project list (future: from Registry/CRM). |
| `company-selector` | Company dropdown | `string` | Pre-populated with Beletage, Urban Switch, Studii de Teren. |
| `tone-selector` | Dropdown | `string` | Options: formal, neutral, technical, persuasive, diplomatic. |
| `regulation-set-selector` | Multi-select | `string[]` | Romanian building codes, urbanism laws, EU directives. |

### Variable Injection

Variables are referenced in block content using `{{variableId}}` syntax. The composition engine replaces placeholders with resolved values.

**Text/number:** Injected as-is.

**Select:** The selected option's `value` is injected. If the label is needed, use `{{variableId.label}}`.

**Multi-select / tag-selector:** Injected as a comma-separated list by default. The composition engine formats arrays according to the provider profile's preference (comma list, bullet list, numbered list).

**Boolean:** Drives conditional blocks via `truthy`/`falsy` operators. Not typically injected as text. If referenced directly, resolves to `"da"` / `"nu"`.

---

## Composition Engine

The composition engine is the core runtime that transforms a template + variable values + provider profile into a final prompt string.

### Pipeline

```
1. Collect variable values from the user form
     |
2. Validate all required variables are filled
     |
3. Evaluate conditional blocks
     |
4. Sort blocks by order (ascending)
     |
5. Filter out:
     - Disabled conditional blocks
     - Optional blocks with no variable content (all placeholders empty)
     |
6. For each remaining block:
     a. Replace {{variable}} placeholders with resolved values
     b. Apply array formatting (comma list, bullet list, etc.)
     c. Trim whitespace
     |
7. Join blocks with separator (double newline by default)
     |
8. Append safety blocks (if enabled)
     |
9. Apply provider profile formatting:
     - Truncate to maxLength (if set)
     - Adjust verbosity (expand or compress instructions)
     - Format for instruction style (direct, conversational, system-prompt)
     - Apply formatting preference (markdown headers, plain text, structured tags)
     |
10. Output final prompt string
```

### Implementation

```typescript
// src/modules/prompt-generator/services/composition-engine.ts

interface CompositionInput {
  template: PromptTemplate;
  values: Record<string, unknown>;
  providerProfile?: ProviderProfile;
  outputMode?: OutputMode;
}

interface CompositionResult {
  prompt: string;
  metadata: {
    templateId: string;
    templateVersion: string;
    blockCount: number;
    variableCount: number;
    characterCount: number;
    providerProfile: string | null;
    outputMode: OutputMode;
    timestamp: string;
  };
  warnings: string[];
}

function composePrompt(input: CompositionInput): CompositionResult {
  const { template, values, providerProfile, outputMode } = input;
  const warnings: string[] = [];
  const resolvedMode = outputMode ?? template.outputMode;

  // 1. Validate required variables
  for (const variable of template.variables) {
    if (variable.required && !hasValue(values[variable.id])) {
      throw new CompositionError(`Required variable "${variable.id}" is missing.`);
    }
  }

  // 2. Filter and sort blocks
  const activeBlocks = template.blocks
    .filter(block => evaluateCondition(block, values))
    .filter(block => block.required || hasBlockContent(block, values))
    .sort((a, b) => a.order - b.order);

  // 3. Resolve blocks
  const resolvedBlocks = activeBlocks.map(block =>
    resolveBlock(block, values, template.variables)
  );

  // 4. Join
  let prompt = resolvedBlocks.join('\n\n');

  // 5. Append safety blocks
  if (template.safetyBlocks?.length) {
    const safetyContent = template.safetyBlocks
      .filter(sb => sb.enabled)
      .map(sb => sb.content)
      .join('\n');
    if (safetyContent) {
      prompt += '\n\n' + safetyContent;
    }
  }

  // 6. Apply provider profile
  if (providerProfile) {
    prompt = applyProviderProfile(prompt, providerProfile, warnings);
  }

  return {
    prompt,
    metadata: {
      templateId: template.id,
      templateVersion: template.version,
      blockCount: activeBlocks.length,
      variableCount: Object.keys(values).length,
      characterCount: prompt.length,
      providerProfile: providerProfile?.id ?? null,
      outputMode: resolvedMode,
      timestamp: new Date().toISOString(),
    },
    warnings,
  };
}
```

### Variable Resolution

```typescript
function resolveBlock(
  block: PromptBlock,
  values: Record<string, unknown>,
  variables: PromptVariable[]
): string {
  let content = block.content;

  // Replace all {{variableId}} placeholders
  const placeholderPattern = /\{\{(\w+)(?:\.(\w+))?\}\}/g;

  content = content.replace(placeholderPattern, (match, varId, property) => {
    const variable = variables.find(v => v.id === varId);
    if (!variable) return match; // leave unresolved placeholders as-is

    const value = values[varId];
    if (value === undefined || value === null || value === '') return '';

    // Handle property access (e.g., {{variable.label}})
    if (property === 'label' && variable.options) {
      const option = variable.options.find(o => o.value === value);
      return option?.label ?? String(value);
    }

    // Handle arrays (multi-select, tag-selector)
    if (Array.isArray(value)) {
      return value.join(', ');
    }

    // Handle booleans
    if (typeof value === 'boolean') {
      return value ? 'da' : 'nu';
    }

    return String(value);
  });

  return content.trim();
}
```

### Conditional Evaluation

```typescript
function evaluateCondition(
  block: PromptBlock,
  values: Record<string, unknown>
): boolean {
  if (!block.conditional) return true;

  const { variableId, operator, value: expectedValue } = block.conditional;
  const actualValue = values[variableId];

  switch (operator) {
    case 'truthy':
      return Boolean(actualValue);
    case 'falsy':
      return !actualValue;
    case 'equals':
      return String(actualValue) === String(expectedValue);
    case 'notEquals':
      return String(actualValue) !== String(expectedValue);
    default:
      return true;
  }
}
```

---

## Output Modes

The output mode controls the structural framing of the composed prompt. It wraps or restructures the assembled blocks to match a desired reasoning style.

| Mode | Description | Use Case |
|---|---|---|
| `short` | Minimal instruction. No preamble, no step enumeration. | Quick queries, image prompts. |
| `expanded-expert` | Full expert-level prompt with detailed role, context, and constraints. | Complex professional tasks. |
| `step-by-step` | Wraps the task block in a numbered step sequence instruction. | Procedural workflows, checklists. |
| `chain-of-thought` | Adds "think step by step" framing, asks for reasoning before conclusion. | Analysis, review, decision-making. |
| `structured-json` | Requests output in a specific JSON schema, includes the schema in the prompt. | Data extraction, structured output. |
| `checklist` | Formats the output requirement as a checklist with pass/fail items. | Compliance review, QA checks. |

---

## Domain Packs

Domain packs are curated bundles of templates, safety blocks, and default provider profiles for a professional domain. They provide a starting point for users in a specific role.

### Available Domain Packs

#### Architecture Visualization

Templates for generating architectural renders, concept imagery, material studies, and presentation graphics.

| Template | Target AI | Description |
|---|---|---|
| Exterior render brief | image | Detailed brief for photorealistic exterior visualization. |
| Interior mood board | image | Style and material palette for interior spaces. |
| Concept sketch directive | image | Abstract/conceptual architectural sketch instructions. |
| Material study | image | Close-up material and texture specifications. |
| Site context rendering | image | Aerial/contextual rendering with surroundings. |

#### Technical Documentation

Templates for generating technical descriptions, specifications, and reports.

| Template | Target AI | Description |
|---|---|---|
| Technical memorandum | text | Structured technical memo for project documentation. |
| Specification writer | text | Material/system specification in Romanian standard format. |
| Site analysis summary | text | Site conditions and constraints synthesis. |
| Meeting minutes structurer | text | Meeting notes formatted to standard template. |
| Design brief elaborator | text | Expand a brief design intent into a full brief. |

#### Legal Review

Templates for legal document analysis, contract review, and regulatory compliance.

| Template | Target AI | Description |
|---|---|---|
| Contract clause reviewer | review | Analyze contract clauses for risks and missing provisions. |
| Regulatory compliance check | review | Check project documentation against specific regulations. |
| Legal response drafter | text | Draft formal legal responses in Romanian administrative style. |
| Permit application reviewer | review | Review building permit application for completeness. |
| Urban certificate analyzer | review | Analyze urbanism certificate conditions and constraints. |

#### Urbanism / GIS

Templates for urban planning analysis, GIS data interpretation, and regulatory land-use review.

| Template | Target AI | Description |
|---|---|---|
| PUZ/PUD analysis | text | Analyze zonal/detailed urban plan provisions. |
| Land use assessment | text | Evaluate land use compatibility and zoning constraints. |
| GIS data descriptor | text | Describe spatial data layers and their implications. |
| Urban indicators calculator | text | Calculate urban indicators (CUT, POT, regim de inaltime). |

#### BIM Coordination

Templates for BIM model review, clash detection reporting, and LOD specification.

| Template | Target AI | Description |
|---|---|---|
| Clash detection report | text | Structure clash detection results into actionable report. |
| LOD specification | text | Define level of development requirements per discipline. |
| Model audit checklist | checklist | QA checklist for BIM model compliance. |
| BEP section drafter | text | Draft sections of a BIM Execution Plan. |

#### Procurement / Bidding

Templates for preparing procurement documents, bid evaluations, and cost analyses.

| Template | Target AI | Description |
|---|---|---|
| Bid evaluation matrix | text | Structure criteria and scoring for bid evaluation. |
| Caiet de sarcini drafter | text | Draft technical specifications (caiet de sarcini) sections. |
| Cost estimate reviewer | review | Review cost estimates for completeness and reasonableness. |
| Procurement timeline | text | Generate procurement schedule with milestones. |

#### Formal Romanian Administrative Writing

Templates for official correspondence, institutional communication, and public administration documents.

| Template | Target AI | Description |
|---|---|---|
| Adresa oficiala | text | Formal letter to public institution. |
| Cerere/solicitare | text | Formal request document. |
| Nota interna | text | Internal memo in institutional format. |
| Raport de activitate | text | Activity report with standardized structure. |
| Proces verbal | text | Minutes/official record in Romanian administrative format. |

---

## Provider Profiles

### Interface

```typescript
interface ProviderProfile {
  id: string;
  name: string;
  maxLength?: number;
  formattingPreference: 'markdown' | 'plain' | 'structured';
  instructionStyle: 'direct' | 'conversational' | 'system-prompt';
  verbosityLevel: 'concise' | 'standard' | 'detailed';
}
```

### Default Profiles

```typescript
const defaultProfiles: ProviderProfile[] = [
  {
    id: 'chatgpt',
    name: 'ChatGPT (GPT-4)',
    maxLength: 8000,
    formattingPreference: 'markdown',
    instructionStyle: 'system-prompt',
    verbosityLevel: 'standard',
  },
  {
    id: 'claude',
    name: 'Claude',
    maxLength: 16000,
    formattingPreference: 'markdown',
    instructionStyle: 'direct',
    verbosityLevel: 'detailed',
  },
  {
    id: 'midjourney',
    name: 'Midjourney',
    maxLength: 500,
    formattingPreference: 'plain',
    instructionStyle: 'direct',
    verbosityLevel: 'concise',
  },
  {
    id: 'copilot',
    name: 'GitHub Copilot',
    maxLength: 4000,
    formattingPreference: 'markdown',
    instructionStyle: 'direct',
    verbosityLevel: 'concise',
  },
  {
    id: 'generic',
    name: 'Generic / Other',
    formattingPreference: 'markdown',
    instructionStyle: 'direct',
    verbosityLevel: 'standard',
  },
];
```

### Provider Profile Application

```typescript
function applyProviderProfile(
  prompt: string,
  profile: ProviderProfile,
  warnings: string[]
): string {
  let result = prompt;

  // Truncate if over maxLength
  if (profile.maxLength && result.length > profile.maxLength) {
    warnings.push(
      `Prompt truncated from ${result.length} to ${profile.maxLength} characters for ${profile.name}.`
    );
    result = result.slice(0, profile.maxLength);
  }

  // Strip markdown for plain profiles
  if (profile.formattingPreference === 'plain') {
    result = stripMarkdown(result);
  }

  // Wrap in system-prompt format if needed
  if (profile.instructionStyle === 'system-prompt') {
    result = wrapAsSystemPrompt(result);
  }

  return result;
}
```

---

## Safety Blocks

Safety blocks are optional, toggleable sections appended to prompts to enforce professional standards.

### Interface

```typescript
interface SafetyBlock {
  id: string;
  label: string;             // Romanian
  content: string;
  enabled: boolean;          // default state; user can toggle
  category: 'legal' | 'tone' | 'citation' | 'disclaimer';
}
```

### Default Safety Blocks

```typescript
const defaultSafetyBlocks: SafetyBlock[] = [
  {
    id: 'legal-tone',
    label: 'Ton juridic formal',
    content: 'Utilizeaza exclusiv limbaj juridic formal, conform practicii legislative si administrative romanesti. Evita formulari colocviale sau ambigue din punct de vedere juridic.',
    enabled: false,
    category: 'tone',
  },
  {
    id: 'neutral-tone',
    label: 'Ton neutru si obiectiv',
    content: 'Mentine un ton neutru, obiectiv si profesional pe tot parcursul raspunsului. Evita formulari subiective, emotionale sau persuasive.',
    enabled: false,
    category: 'tone',
  },
  {
    id: 'normative-refs',
    label: 'Cerinta referinte normative',
    content: 'Citeaza toate actele normative aplicabile (legi, hotarari de guvern, ordine, norme tehnice) cu numar, data si titlu complet. Indica articolele si alineatele relevante.',
    enabled: false,
    category: 'citation',
  },
  {
    id: 'uncertainty-disclaimer',
    label: 'Disclaimer incertitudine',
    content: 'Semnaleaza explicit orice incertitudine, ambiguitate sau lipsa de informatii. Delimiteaza clar informatiile factuale de interpretari sau presupuneri. Indica cazurile in care este necesara verificarea de catre un specialist.',
    enabled: false,
    category: 'disclaimer',
  },
  {
    id: 'source-citation',
    label: 'Cerinta citare surse',
    content: 'Citeaza sursa fiecarei informatii factuale prezentate. Pentru reglementari, indica actul normativ specific. Pentru standarde, indica codul si anul editiei. Pentru date tehnice, indica sursa si data accesarii.',
    enabled: false,
    category: 'citation',
  },
];
```

### Usage

Safety blocks are toggleable per template. When a template is loaded, the form shows toggles for each safety block. The user can enable or disable them before composing the prompt. Enabled safety blocks are appended after all content blocks, separated by a delimiter line.

---

## UX Flow

### Primary Flow

```
1. User opens Prompt Generator module
     |
2. Domain selector: user picks a professional domain
     (architecture-visualization, legal-review, etc.)
     |
3. Template list filters to show only templates in the selected domain
     User can also search/filter by tags, category, or AI type
     |
4. User selects a template
     |
5. Variable form renders:
     - Required variables marked with indicator
     - Default values pre-filled
     - Helper text shown below each input
     - Selectors (tag, project, company, tone, regulation) render
       appropriate picker components
     |
6. Live preview panel updates as the user fills variables
     - Shows the composed prompt in real time
     - Conditional blocks appear/disappear as conditions change
     - Character count and provider compatibility shown
     |
7. Advanced mode (toggle):
     - Output mode selector (short, expanded-expert, etc.)
     - Provider profile selector
     - Safety block toggles
     - Block reordering (drag and drop)
     - Custom block insertion
     |
8. Actions:
     - Copy to clipboard (primary action)
     - Save to history
     - Add to favorites
     - Export as JSON (for sharing or backup)
     - Send to AI Chat module (opens AI Chat with prompt pre-filled)
     - Save as custom template (forks the template with current variable defaults)
```

### Layout

```
┌─────────────────────────────────────────────────────────────────────┐
│  Prompt Generator                                        [Advanced] │
├──────────────────────┬──────────────────────────────────────────────┤
│                      │                                              │
│  Domain: [dropdown]  │  PREVIEW                                     │
│                      │                                              │
│  ┌────────────────┐  │  ┌────────────────────────────────────────┐  │
│  │ Template List   │  │  │                                        │  │
│  │                 │  │  │  Esti un arhitect specialist in        │  │
│  │ > Exterior...   │  │  │  proiectare rezidentiala cu 15 ani     │  │
│  │   Interior...   │  │  │  experienta in {{context}}...          │  │
│  │   Concept...    │  │  │                                        │  │
│  │   Material...   │  │  │  Sarcina: Genereaza {{task_type}}      │  │
│  │                 │  │  │  pentru proiectul {{project_name}}...  │  │
│  └────────────────┘  │  │                                        │  │
│                      │  │  Constrangeri:                          │  │
│  VARIABLES           │  │  - {{constraints}}                      │  │
│  ┌────────────────┐  │  │                                        │  │
│  │ Proiect:       │  │  │  Format: {{output_format}}             │  │
│  │ [__________]   │  │  │                                        │  │
│  │                │  │  └────────────────────────────────────────┘  │
│  │ Tip sarcina:   │  │                                              │
│  │ [dropdown   ]  │  │  Characters: 1,247 / 8,000                   │
│  │                │  │  Provider: ChatGPT (GPT-4)                   │
│  │ Context:       │  │                                              │
│  │ [__________]   │  │  [Copy] [Save] [Send to AI Chat] [Export]   │
│  │ [__________]   │  │                                              │
│  └────────────────┘  │                                              │
│                      │                                              │
├──────────────────────┴──────────────────────────────────────────────┤
│  Safety: [ ] Ton juridic  [ ] Ton neutru  [x] Disclaimer           │
└─────────────────────────────────────────────────────────────────────┘
```

---

## Integration with Other Modules

### Tag Manager

The Prompt Generator uses the platform tagging system for:
- Template tagging (categorization, search, filtering).
- The `tag-selector` variable type, which renders the shared tag picker component.
- Prompt history entries can be tagged for organization.

Integration is through the shared tagging service (`src/core/tagging/`), not through direct module imports.

### AI Chat

Generated prompts can be sent directly to the AI Chat module. The flow:
1. User composes a prompt in Prompt Generator.
2. User clicks "Send to AI Chat."
3. The platform navigates to the AI Chat module with the prompt pre-filled in the input field.

Communication mechanism: URL query parameter (`/ai-chat?prompt=<encoded>`) or a shared transient state service in `src/lib/`. The Prompt Generator does not import from the AI Chat module directly.

### Registry (Registratura)

Prompts can be attached to registry entries as metadata. Use cases:
- Attach the prompt used to generate a document to the document's registry entry.
- Link prompt templates to specific project phases or document types.

Integration: The Prompt Generator exposes a "Link to Registry" action that stores a reference (prompt history ID) in the registry entry's metadata.

### Word Templates

Prompt output can feed into Word template generation:
1. User generates structured text via Prompt Generator (e.g., a technical memorandum).
2. User sends the output to the Word Template module for formatting into a `.docx` file.
3. The Word Template module receives the text as variable input.

Integration: Similar to AI Chat -- URL parameter or shared transient state. No direct module imports.

---

## Prompt History

### Storage

Prompt history is persisted via the platform storage abstraction under the `prompt-generator` namespace.

```typescript
interface PromptHistoryEntry {
  id: string;
  templateId: string;
  templateName: string;
  templateVersion: string;
  values: Record<string, unknown>;
  composedPrompt: string;
  outputMode: OutputMode;
  providerProfile: string | null;
  safetyBlocks: string[];        // IDs of enabled safety blocks
  tags: string[];
  isFavorite: boolean;
  createdAt: string;             // ISO 8601
  metadata?: Record<string, unknown>;
}
```

### Storage Keys

| Key Pattern | Content |
|---|---|
| `history::{id}` | Individual history entry. |
| `favorites` | Array of favorite history entry IDs. |
| `recent-templates` | Array of recently used template IDs (last 10). |

### Capabilities

- **Save:** Every composed prompt can be saved to history with one click.
- **Favorites:** Mark history entries as favorites for quick access.
- **Version comparison:** When a template version changes, compare the old composed output with a new composition using the same variable values.
- **Search:** Full-text search across history entries (prompt text, template name, tags).
- **Export:** Export history as JSON for backup or sharing.

---

## Module Structure

```
src/modules/prompt-generator/
  components/
    TemplateSelector.tsx         # Domain filter + template list + search
    VariableForm.tsx             # Auto-generated form from template variables
    BlockEditor.tsx              # Block reordering, custom block insertion (advanced mode)
    PromptPreview.tsx            # Live preview panel with character count
    DomainPackBrowser.tsx        # Domain pack overview and template browsing
    ProviderProfileSelector.tsx  # Provider profile dropdown with profile details
    PromptHistory.tsx            # History list, favorites, search, version comparison
  hooks/
    usePromptComposer.ts         # Core composition state: template, values, preview
    useTemplateManager.ts        # Template CRUD, custom template creation
    usePromptHistory.ts          # History persistence, favorites, search
    useDomainPacks.ts            # Domain pack loading and filtering
  services/
    composition-engine.ts        # Template + values + profile --> final prompt
    template-service.ts          # Template loading, validation, custom template storage
    variable-resolver.ts         # Variable value resolution, validation, formatting
  data/
    default-templates.ts         # Built-in template definitions
    domain-packs.ts              # Domain pack configurations
    provider-profiles.ts         # Default provider profiles
    safety-blocks.ts             # Default safety block definitions
  types.ts                       # All TypeScript interfaces (PromptTemplate, PromptBlock, etc.)
  config.ts                      # ModuleConfig for the registry
  index.ts                       # Barrel export
```

### Component Responsibilities

| Component | Responsibility |
|---|---|
| `TemplateSelector` | Renders domain filter dropdown, template list with search, category badges, and AI type indicators. Emits selected template to parent. |
| `VariableForm` | Receives a `PromptVariable[]` array, renders the appropriate input control for each variable type, validates input, and emits value changes. Does not know about templates or composition. |
| `BlockEditor` | Advanced mode only. Shows block list with drag-and-drop reordering, inline content editing, and custom block insertion. |
| `PromptPreview` | Receives the composed prompt string and renders it with syntax highlighting, character count, provider compatibility indicator, and copy button. |
| `DomainPackBrowser` | Shows domain packs as cards with template counts. Clicking a pack filters the template list. |
| `ProviderProfileSelector` | Dropdown with provider profile details (max length, formatting, instruction style). |
| `PromptHistory` | Tabbed view: Recent, Favorites, All. Each entry shows template name, date, preview snippet, and actions (re-use, compare, delete). |

### Hook Responsibilities

| Hook | Responsibility |
|---|---|
| `usePromptComposer` | Central composition state. Manages selected template, variable values, output mode, provider profile, safety block toggles. Calls composition engine on value changes. Returns composed prompt and metadata. |
| `useTemplateManager` | Loads default and custom templates. Handles custom template creation (forking a default template with modified defaults). Persists custom templates to storage. |
| `usePromptHistory` | CRUD for prompt history entries. Favorites management. Search and filtering. Uses `useStorage('prompt-generator')`. |
| `useDomainPacks` | Loads domain pack configurations. Provides filtered template lists per domain. Tracks recently used domains. |

### Service Responsibilities

| Service | Responsibility |
|---|---|
| `composition-engine.ts` | Pure function: `composePrompt(template, values, profile) -> result`. No side effects, no state, no storage access. Fully testable. |
| `template-service.ts` | Template validation (required fields, block consistency, variable references). Custom template persistence via storage abstraction. Template versioning. |
| `variable-resolver.ts` | Variable value validation against type constraints. Default value resolution. Array formatting (comma list, bullet list). Boolean-to-text conversion. |

---

## Module Configuration

```typescript
// src/modules/prompt-generator/config.ts

import { ModuleConfig } from '@/types/modules';

export const promptGeneratorConfig: ModuleConfig = {
  id: 'prompt-generator',
  name: 'Generator Prompturi',
  description: 'Generator structurat de prompturi pe baza sabloanelor parametrizate, organizate pe domenii profesionale.',
  icon: 'wand-sparkles',
  route: '/prompt-generator',
  category: 'ai',
  featureFlag: 'module.prompt-generator',
  visibility: 'all',
  version: '1.0.0',
  dependencies: [],
  storageNamespace: 'prompt-generator',
  navOrder: 20,
  tags: ['prompt', 'ai', 'generator', 'templates'],
};
```

---

## Anti-Patterns

### No Hardcoded Templates in UI Components

Templates live in `data/default-templates.ts` and custom templates in storage. Components render templates dynamically from the template list. A component must never contain a prompt template string directly.

**Wrong:**
```typescript
// Inside TemplateSelector.tsx
const templates = [
  { name: 'Legal Review', content: 'Esti un avocat specialist...' },
];
```

**Right:**
```typescript
// In data/default-templates.ts
export const defaultTemplates: PromptTemplate[] = [
  {
    id: 'legal-contract-review',
    name: 'Revizuire contract',
    // ... full template definition
  },
];

// In TemplateSelector.tsx
function TemplateSelector({ templates }: { templates: PromptTemplate[] }) {
  // render from props, never from inline data
}
```

### No Provider-Specific Logic in Templates

Templates are provider-agnostic. Provider-specific formatting (max length, instruction style, verbosity) is applied by the composition engine using the selected provider profile. A template must never contain conditional logic for specific providers.

**Wrong:**
```typescript
{
  content: 'You are a legal expert. {{#if provider === "midjourney"}}Keep it under 500 chars.{{/if}}',
}
```

**Right:**
```typescript
// Template contains only the core instruction
{
  content: 'Esti un expert juridic specializat in {{domain}}.',
}
// Provider profile controls length and formatting
```

### No Inline Romanian Text

All Romanian-language strings used in the UI (labels, placeholders, helper text, error messages) must come from the variable/block definitions or the platform i18n system. Components must not contain inline Romanian strings.

**Wrong:**
```typescript
<label>Selecteaza domeniul profesional:</label>
```

**Right:**
```typescript
<label>{variable.label}</label>
// where variable.label = 'Domeniu profesional' from the variable definition
```

Or through the i18n system:
```typescript
<label>{useLabel('prompt-generator.domainSelector')}</label>
```

---

## Data Flow

### Template Selection to Prompt Output

```
User selects domain
  --> useDomainPacks filters templates
    --> TemplateSelector renders filtered list
      --> User selects template
        --> usePromptComposer loads template
          --> VariableForm renders from template.variables
            --> User fills variables
              --> usePromptComposer calls composePrompt()
                --> composition-engine resolves blocks + variables
                  --> PromptPreview renders result
                    --> User copies / saves / exports
```

### Custom Template Creation

```
User fills variables on an existing template
  --> User clicks "Save as custom template"
    --> useTemplateManager.fork(templateId, currentValues)
      --> Creates a new PromptTemplate with:
           - New ID (uuid)
           - Current variable values as new defaultValues
           - Author set to current user
           - Version "1.0.0"
      --> template-service persists to storage (prompt-generator::custom-templates)
        --> Custom template appears in the template list
```

### Prompt History Save

```
User composes a prompt
  --> User clicks "Save"
    --> usePromptHistory.save(compositionResult)
      --> Creates PromptHistoryEntry with:
           - Snapshot of template ID, version, values, composed prompt
           - Timestamp
      --> Persists to storage (prompt-generator::history::{id})
        --> PromptHistory component updates
```
