{"id": "doctype-mockdoca", "type": "doctype", "title": "DocType: MockDocA", "content": "# MockDocA\n\n**Source**: [verify_selective_migrations.py](file:///builds/castlecraft/framework-m/scripts/verify_selective_migrations.py)\n\n## Fields\n\n_No fields defined._\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "MockDocA"}} {"id": "doctype-todo", "type": "doctype", "title": "DocType: Todo", "content": "# Todo\n\nTodo DocType for testing.\n\n**Source**: [run_server.py](file:///builds/castlecraft/framework-m/libs/framework-m/examples/run_server.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| title | str | | Todo title | - |\n| completed | bool | | - | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Employee | \u2713 | | \u2713 | \u2713 |\n| Guest | | | \u2713 | |\n| Manager | \u2713 | | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Todo"}} {"id": "doctype-scheduledjob", "type": "doctype", "title": "DocType: ScheduledJob", "content": "# ScheduledJob\n\nPersistent scheduled job configuration.\n\n Stores cron job definitions that are loaded by the worker\n process at startup, enabling dynamic job scheduling.\n\n Attributes:\n name: Unique job identifier\n function: Dotted path to job function (e.g., 'myapp.jobs.send_email')\n cron_expression: Cron syntax string (e.g., '0 9 * * *')\n enabled: Whether the job is active\n last_run: Timestamp of last execution (updated by worker)\n next_run: Timestamp of next scheduled run (calculated)\n\n**Source**: [scheduled_job.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/scheduled_job.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| name | str | \u2713 | Unique job identifier | minLen: 1, maxLen: 255 |\n| function | str | \u2713 | Dotted path to job function (e.g., 'myapp.jobs.send_email') | minLen: 1 |\n| cron_expression | str | \u2713 | Cron syntax (e.g., '0 9 * * *' for daily at 9 AM) | minLen: 1 |\n| enabled | bool | | Whether the job is active and should be scheduled | - |\n| last_run | datetime | None | | Timestamp of last execution (set by worker) | - |\n| next_run | datetime | None | | Timestamp of next scheduled run (calculated) | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Employee | | | \u2713 | |\n| Manager | \u2713 | | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "ScheduledJob"}} {"id": "doctype-todo", "type": "doctype", "title": "DocType: Todo", "content": "# Todo\n\nA simple todo item.\n\n Attributes:\n title: The title/name of the todo item\n description: Optional description of the todo\n completed: Whether the todo is completed\n priority: Priority level (Low, Medium, High)\n\n**Source**: [todo.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/todo.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| title | str | | Title of the todo item | minLen: 1, maxLen: 200 |\n| description | str | None | | Optional description | maxLen: 1000 |\n| completed | bool | | Whether the todo is completed | - |\n| priority | str | | Priority level | pattern: `^(Low|Medium|High)$` |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Todo"}} {"id": "doctype-translation", "type": "doctype", "title": "DocType: Translation", "content": "# Translation\n\nTranslation for multilingual text.\n\n Attributes:\n source_text: Original text in default language (usually English)\n translated_text: Translated text in target locale\n locale: Target locale code (e.g., \"fr\", \"es\", \"hi\", \"ta\")\n context: Optional context for disambiguation (e.g., \"button\", \"label\", \"error\")\n\n Constraints:\n Unique: (source_text, locale, context) - prevents duplicate translations\n\n Example:\n # Simple translation\n t1 = Translation(\n source_text=\"Save\",\n translated_text=\"Enregistrer\",\n locale=\"fr\",\n )\n\n # Context-aware translation\n t2 = Translation(\n source_text=\"Save\",\n translated_text=\"Sauvegarder\",\n locale=\"fr\",\n context=\"button\",\n )\n\n**Source**: [translation.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/translation.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| source_text | str | | Original text in default language | minLen: 1, maxLen: 1000 |\n| translated_text | str | | Translated text in target locale | minLen: 1, maxLen: 1000 |\n| locale | str | | Target locale code (e.g., 'fr', 'es', 'hi') | minLen: 2, maxLen: 10, pattern: `^[a-z]{2}(_[A-Z]{2})?$` |\n| context | str | None | | Optional context for disambiguation | maxLen: 100 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Translation"}} {"id": "doctype-errorlog", "type": "doctype", "title": "DocType: ErrorLog", "content": "# ErrorLog\n\nError log entry DocType.\n\n Stores information about system errors for debugging.\n Errors are captured by the global exception handler.\n\n Attributes:\n title: Short description of the error\n error_type: Exception class name (e.g., \"ValueError\")\n error_message: Full error message\n traceback: Stack trace for debugging\n request_url: URL that triggered the error\n user_id: User who triggered the error\n request_id: Request ID for correlation\n timestamp: When the error occurred\n context: Additional context (headers, params, etc.)\n\n Example:\n log = ErrorLog(\n title=\"Validation failed\",\n error_type=\"ValidationError\",\n error_message=\"Field 'email' is invalid\",\n )\n\n**Source**: [error_log.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/error_log.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| title | str | \u2713 | Short description of the error | maxLen: 255 |\n| error_type | str | \u2713 | Exception class name (e.g., ValueError) | - |\n| error_message | str | \u2713 | Full error message | - |\n| traceback | str | None | | Full stack trace for debugging | - |\n| request_url | str | None | | URL that triggered the error | - |\n| user_id | str | None | | User who triggered the error | - |\n| request_id | str | None | | Request ID for log correlation | - |\n| timestamp | datetime | | When the error occurred (UTC) | - |\n| context | dict[str, Any] | None | | Additional context: headers, params, etc. | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| System Manager | \u2713 | | \u2713 | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "ErrorLog"}} {"id": "doctype-workflowstate", "type": "doctype", "title": "DocType: WorkflowState", "content": "# WorkflowState\n\nTracks the current workflow state of a document.\n\n Attributes:\n workflow: Name of the workflow\n doctype: The DocType of the document in workflow\n document_name: The name/ID of the document\n current_state: Current state name in the workflow\n updated_at: When the state was last updated\n\n**Source**: [workflow_state.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/workflow_state.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| workflow | str | | Workflow name | - |\n| doctype | str | | Target DocType | - |\n| document_name | str | | Document ID | - |\n| current_state | str | | Current workflow state | - |\n| updated_at | datetime | | Last state update timestamp | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "WorkflowState"}} {"id": "doctype-tenanttranslation", "type": "doctype", "title": "DocType: TenantTranslation", "content": "# TenantTranslation\n\nTenant-specific translation overrides.\n\n Allows tenants to customize translations to match their terminology,\n industry, or brand voice. Overrides system translations when present.\n\n Attributes:\n tenant_id: Tenant identifier (from TenantContext)\n source_text: Original text to translate (1-1000 characters)\n translated_text: Translated text in target locale (1-1000 characters)\n locale: Locale code (e.g., \"en\", \"hi\", \"ta\", \"es_MX\")\n context: Optional context for disambiguation (e.g., \"button\", \"field_label\")\n\n Constraints:\n - Unique combination of (tenant_id, source_text, locale, context)\n - locale must match pattern: 2 lowercase letters, optionally followed by\n underscore and 2 uppercase letters (e.g., \"en\", \"en_US\", \"pt_BR\")\n\n Example:\n # Healthcare tenant uses \"Patient\" instead of \"Customer\"\n TenantTranslation(\n tenant_id=\"healthcare-corp\",\n source_text=\"Customer\",\n translated_text=\"Patient\",\n locale=\"en\",\n context=\"field_label\"\n )\n\n # Retail tenant uses \"Client\" in French\n TenantTranslation(\n tenant_id=\"retail-corp\",\n source_text=\"Customer\",\n translated_text=\"Client\",\n locale=\"fr\",\n context=\"field_label\"\n )\n\n**Source**: [tenant_translation.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/tenant_translation.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| tenant_id | str | | Tenant identifier from TenantContext | minLen: 1, maxLen: 100 |\n| source_text | str | | Original text to translate | minLen: 1, maxLen: 1000 |\n| translated_text | str | | Translated text in target locale | minLen: 1, maxLen: 1000 |\n| locale | str | | Locale code (e.g., 'en', 'hi', 'ta', 'es_MX') | minLen: 2, maxLen: 10, pattern: `^[a-z]{2}(_[A-Z]{2})?$` |\n| context | str | None | | Optional context for disambiguation (e.g., 'button', 'field_label') | maxLen: 100 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "TenantTranslation"}} {"id": "doctype-notification", "type": "doctype", "title": "DocType: Notification", "content": "# Notification\n\nNotification DocType.\n\n Stores in-app notifications for users.\n\n Attributes:\n user_id: Recipient user ID\n subject: Notification subject/title\n message: Full notification message\n notification_type: Type of notification (info, success, etc.)\n read: Whether the notification has been read\n doctype: Related DocType (optional)\n document_id: Related document ID (optional)\n timestamp: When the notification was created\n from_user: User who triggered the notification (optional)\n metadata: Additional notification data\n\n Example:\n notification = Notification(\n user_id=\"user-001\",\n subject=\"New Comment\",\n message=\"John commented on your invoice.\",\n )\n\n**Source**: [notification.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/notification.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| user_id | str | \u2713 | Recipient user ID | - |\n| subject | str | \u2713 | Notification subject/title | maxLen: 255 |\n| message | str | \u2713 | Full notification message | - |\n| notification_type | str | | Notification type (info, success, warning, error, etc.) | - |\n| read | bool | | Whether the notification has been read | - |\n| doctype | str | None | | Related DocType (e.g., Invoice) | - |\n| document_id | str | None | | Related document ID | - |\n| timestamp | datetime | | When the notification was created (UTC) | - |\n| from_user | str | None | | User who triggered the notification | - |\n| metadata | dict[str, Any] | None | | Additional notification data | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| All | | \u2713 | \u2713 | \u2713 |\n| System Manager | \u2713 | | | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Notification"}} {"id": "doctype-localuser", "type": "doctype", "title": "DocType: LocalUser", "content": "# LocalUser\n\nSQL-backed user for Indie mode (Mode A).\n\n Stores credentials and profile information locally.\n Default implementation for rapid development.\n\n Attributes:\n email: Unique email address (login identifier)\n password_hash: Argon2 hash of password (excluded from serialization)\n full_name: Optional display name\n is_active: Whether user can log in (default True)\n\n Security:\n - password_hash is excluded from model_dump() and model_dump_json()\n - Never store plaintext passwords\n - Use argon2 for hashing (see LocalIdentityAdapter)\n\n Example:\n user = LocalUser(\n email=\"john@example.com\",\n password_hash=\"$argon2id$v=19$...\",\n full_name=\"John Doe\",\n )\n\n**Source**: [user.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/user.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| email | str | | Unique email address | - |\n| password_hash | str | | Argon2 password hash | - |\n| full_name | str | None | | User's display name | - |\n| is_active | bool | | Whether user can log in | - |\n| locale | str | None | | User's preferred locale (e.g., 'en', 'hi', 'ta') | maxLen: 10 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "LocalUser"}} {"id": "doctype-apikey", "type": "doctype", "title": "DocType: ApiKey", "content": "# ApiKey\n\nAPI key for scripts and integrations.\n\n Attributes:\n key_hash: Argon2 hash of the API key (excluded from serialization)\n user_id: Owner of the key\n name: Human-readable label for the key\n scopes: Optional permission scopes (e.g., [\"read\", \"write\"])\n expires_at: Optional expiration date\n last_used_at: Last time the key was used (for auditing)\n is_active: Whether the key is currently active\n\n Security:\n - key_hash is excluded from model_dump() and model_dump_json()\n - Never store or return plaintext keys\n - Raw key is only shown once at creation time\n\n Example:\n key = ApiKey(\n key_hash=\"$argon2id$v=19$...\",\n user_id=\"user-123\",\n name=\"Production Deployment\",\n scopes=[\"deploy\"],\n expires_at=datetime(2025, 12, 31),\n )\n\n**Source**: [api_key.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/api_key.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| key_hash | str | | Argon2 hash of the API key | - |\n| user_id | str | | Owner user ID | - |\n| name | str | | Human-readable key label | - |\n| scopes | list[str] | | Permission scopes for this key | - |\n| expires_at | datetime | None | | Key expiration date (None = never expires) | - |\n| last_used_at | datetime | None | | Last time the key was used | - |\n| is_active | bool | | Whether the key is active | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "ApiKey"}} {"id": "doctype-recentdocument", "type": "doctype", "title": "DocType: RecentDocument", "content": "# RecentDocument\n\nRecentDocument DocType.\n\n Tracks recently viewed documents per user for quick navigation.\n\n Attributes:\n user_id: User who viewed the document\n doctype: DocType of the viewed document\n document_id: ID of the viewed document\n document_name: Display name of the document\n route: URL route to the document\n viewed_at: When the document was last viewed\n\n**Source**: [recent_document.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/recent_document.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| user_id | str | \u2713 | User who viewed the document | - |\n| doctype | str | \u2713 | DocType of the viewed document | - |\n| document_id | str | \u2713 | ID of the viewed document | - |\n| document_name | str | \u2713 | Display name of the document | - |\n| route | str | None | | URL route to the document | - |\n| viewed_at | datetime | | When the document was last viewed | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| All | \u2713 | \u2713 | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "RecentDocument"}} {"id": "doctype-systemsettings", "type": "doctype", "title": "DocType: SystemSettings", "content": "# SystemSettings\n\nSystem settings singleton DocType.\n\n Stores global application configuration. Only one instance exists.\n\n Attributes:\n name: Always \"System Settings\"\n app_name: Application display name\n timezone: Default timezone (e.g., \"UTC\", \"America/New_York\")\n date_format: Date format string (e.g., \"YYYY-MM-DD\")\n time_format: Time format string (e.g., \"HH:mm:ss\")\n language: Default language code (e.g., \"en\")\n enable_signup: Allow new user registration\n session_expiry: Session timeout in minutes\n maintenance_mode: If True, only admins can access\n\n Example:\n settings = SystemSettings(\n app_name=\"My App\",\n timezone=\"America/New_York\",\n )\n\n**Source**: [system_settings.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/system_settings.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| name | str | | Always 'System Settings | - |\n| app_name | str | | Application display name | maxLen: 255 |\n| timezone | str | | Default timezone (e.g., UTC, America/New_York) | - |\n| date_format | str | | Date format (e.g., YYYY-MM-DD, DD/MM/YYYY) | - |\n| time_format | str | | Time format (e.g., HH:mm:ss, hh:mm A) | - |\n| language | str | | Default language code (e.g., en, es, fr) | minLen: 2, maxLen: 10 |\n| enable_signup | bool | | Allow new user registration | - |\n| session_expiry | int | | Session timeout in minutes | min: 1, max: 525600 |\n| maintenance_mode | bool | | If True, only admins can access the application | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| All | | | \u2713 | |\n| System Manager | \u2713 | | | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "SystemSettings"}} {"id": "doctype-documentshare", "type": "doctype", "title": "DocType: DocumentShare", "content": "# DocumentShare\n\nExplicit share of a document with a user or role.\n\n Enables fine-grained document-level sharing beyond the default\n owner-based or team-based RLS.\n\n Attributes:\n doctype_name: The DocType being shared (e.g., \"Invoice\")\n doc_id: Document identifier (e.g., \"INV-001\" or UUID)\n shared_with: User ID or Role name to share with\n share_type: Whether sharing with USER or ROLE\n granted_permissions: List of permissions granted (e.g., [\"read\", \"write\"])\n note: Optional note explaining why the share was created\n\n**Source**: [document_share.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/document_share.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| doctype_name | str | | DocType name of the shared document | - |\n| doc_id | str | | ID or name of the document being shared | - |\n| shared_with | str | | User ID or Role name to share with | - |\n| share_type | ShareType | | Whether sharing with a user or role | - |\n| granted_permissions | list[str] | | Permissions granted: read, write, delete, etc. | - |\n| note | str | None | | Reason for sharing (for audit) | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Employee | \u2713 | | \u2713 | \u2713 |\n| Manager | \u2713 | | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "DocumentShare"}} {"id": "doctype-emailqueue", "type": "doctype", "title": "DocType: EmailQueue", "content": "# EmailQueue\n\nEmail queue DocType.\n\n Stores outbound emails for asynchronous processing.\n\n Attributes:\n to: List of recipient email addresses\n cc: Carbon copy recipients\n bcc: Blind carbon copy recipients\n subject: Email subject line\n body: Email body (HTML)\n text_body: Plain text alternative\n status: Queue status (Queued, Sending, Sent, Failed)\n priority: Email priority (low, normal, high)\n error: Error message if failed\n retry_count: Number of retry attempts\n max_retries: Maximum retry attempts\n queued_at: When the email was queued\n sent_at: When the email was sent\n from_address: Sender email address\n reply_to: Reply-to address\n attachments: Attachment metadata\n reference_doctype: Related DocType (optional)\n reference_id: Related document ID (optional)\n\n Example:\n email = EmailQueue(\n to=[\"user@example.com\"],\n subject=\"Invoice\",\n body=\"
Your invoice is attached.
\",\n )\n\n**Source**: [email_queue.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/email_queue.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| to | list[str] | \u2713 | Recipient email addresses | minLen: 1 |\n| subject | str | \u2713 | Email subject line | maxLen: 500 |\n| body | str | \u2713 | Email body (HTML) | - |\n| cc | list[str] | None | | Carbon copy recipients | - |\n| bcc | list[str] | None | | Blind carbon copy recipients | - |\n| text_body | str | None | | Plain text alternative | - |\n| status | str | | Queue status (Queued, Sending, Sent, Failed) | - |\n| priority | str | | Email priority (low, normal, high) | - |\n| error | str | None | | Error message if failed | - |\n| retry_count | int | | Number of retry attempts | min: 0 |\n| max_retries | int | | Maximum retry attempts | min: 0, max: 10 |\n| queued_at | datetime | | When the email was queued (UTC) | - |\n| sent_at | datetime | None | | When the email was sent (UTC) | - |\n| from_address | str | None | | Sender email address (uses default if not specified) | - |\n| reply_to | str | None | | Reply-to address | - |\n| attachments | list[dict[str, Any]] | None | | Attachment metadata (file_id, filename, content_type) | - |\n| reference_doctype | str | None | | Related DocType (e.g., Invoice) | - |\n| reference_id | str | None | | Related document ID | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| System Manager | \u2713 | \u2713 | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "EmailQueue"}} {"id": "doctype-webhook", "type": "doctype", "title": "DocType: Webhook", "content": "# Webhook\n\nOutgoing webhook configuration.\n\n Defines webhooks that listen to events and deliver HTTP\n notifications to external endpoints with optional filtering.\n\n Attributes:\n name: Unique webhook identifier\n event: Event to listen to (e.g., \"doc.created\", \"doc.updated\")\n doctype_filter: Optional DocType filter (e.g., \"Invoice\")\n condition: Optional JMESPath/SimpleEval expression to filter events\n url: Webhook endpoint URL\n method: HTTP method (POST or PUT)\n headers: Custom HTTP headers to send\n payload_transform: Optional Jinja2 template to transform event payload\n enabled: Whether the webhook is active\n secret: Secret for HMAC-SHA256 signature verification\n\n**Source**: [webhook.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/webhook.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| name | str | \u2713 | Unique webhook identifier | minLen: 1, maxLen: 255 |\n| event | str | \u2713 | Event to listen to (e.g., 'doc.created') | minLen: 1 |\n| doctype_filter | str | None | | Filter by DocType (e.g., 'Invoice', 'Order') | - |\n| condition | str | None | | JMESPath or SimpleEval expression to filter events (e.g., 'status == `paid`') | - |\n| url | str | \u2713 | Webhook endpoint URL | minLen: 1 |\n| method | str | | HTTP method (POST or PUT) | - |\n| headers | dict[str, Any] | | Custom HTTP headers to send with request | - |\n| payload_transform | str | None | | Jinja2 template to transform event payload (e.g., \\'{\"text\": \"{{ doc.name }}\"}\\') | - |\n| enabled | bool | | Whether the webhook is active | - |\n| secret | str | None | | Secret for HMAC-SHA256 signature (X-Webhook-Signature header) | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Manager | | | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Webhook"}} {"id": "doctype-custompermission", "type": "doctype", "title": "DocType: CustomPermission", "content": "# CustomPermission\n\nDatabase-stored permission override.\n\n Allows admins to override code-first permissions with database rules.\n Evaluated in the RbacPermissionAdapter alongside Meta.permissions.\n\n Evaluation Priority:\n 1. Explicit DENY rules are checked first (deny wins)\n 2. If no deny, explicit ALLOW rules are checked\n 3. If no explicit rule, fall back to code-first Meta.permissions\n\n Attributes:\n for_user: Optional user ID this rule applies to\n for_role: Optional role name this rule applies to\n doctype_name: The DocType this permission applies to (\"*\" for all)\n action: The action (read, write, create, delete, submit, etc.)\n effect: Whether to ALLOW or DENY the permission\n enabled: Whether this rule is active\n priority: Rule priority (higher = evaluated first)\n description: Human-readable description of why this rule exists\n\n**Source**: [custom_permission.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/custom_permission.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| for_user | str | None | | User ID this rule applies to (None = all users) | - |\n| for_role | str | None | | Role name this rule applies to (None = all roles) | - |\n| doctype_name | str | | DocType name or '*' for all DocTypes | - |\n| action | str | | Action: read, write, create, delete, submit, cancel, amend | - |\n| effect | PermissionEffect | | Whether to allow or deny this permission | - |\n| enabled | bool | | Whether this rule is active | - |\n| priority | int | | Rule priority (higher = evaluated first) | - |\n| description | str | None | | Why this rule exists (for audit) | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| System | | | \u2713 | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "CustomPermission"}} {"id": "doctype-workflow", "type": "doctype", "title": "DocType: Workflow", "content": "# Workflow\n\nDefines a complete workflow configuration.\n\n Attributes:\n doctype: The target DocType this workflow applies to\n initial_state: The starting state for new documents\n states: List of state definitions with metadata\n is_active: Whether this workflow is currently active\n\n**Source**: [workflow.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/workflow.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| doctype | str | | Target DocType for this workflow | - |\n| initial_state | str | | Initial state for new documents | - |\n| states | list[dict[str, str]] | | State definitions with name and optional metadata | - |\n| is_active | bool | | Whether workflow is active | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Workflow"}} {"id": "doctype-socialaccount", "type": "doctype", "title": "DocType: SocialAccount", "content": "# SocialAccount\n\nLinks OAuth2/OIDC provider identity to local user.\n\n Attributes:\n provider: OAuth2 provider name (google, github, microsoft, oidc)\n provider_user_id: Unique ID from the provider\n user_id: Local user ID this account belongs to\n display_name: Display name from provider (for UI)\n email: Email from provider (for lookup, optional)\n last_login_at: Last time this social account was used\n\n Security:\n - No sensitive data (tokens, secrets) stored here\n - Only identity linking information\n - Tokens are handled by OAuth2 flow, not persisted\n\n Example:\n # User signs in with Google\n account = SocialAccount(\n provider=\"google\",\n provider_user_id=\"1234567890\",\n user_id=\"user-001\",\n display_name=\"John Doe\",\n )\n\n**Source**: [social_account.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/social_account.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| provider | str | | OAuth2 provider (google, github, microsoft, oidc) | - |\n| provider_user_id | str | | Unique user ID from the provider | - |\n| user_id | str | | Local user ID this account belongs to | - |\n| display_name | str | | Display name from provider | - |\n| email | str | None | | Email from provider (for lookup) | - |\n| last_login_at | datetime | None | | Last time this social account was used for login | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "SocialAccount"}} {"id": "doctype-webhooklog", "type": "doctype", "title": "DocType: WebhookLog", "content": "# WebhookLog\n\nWebhook delivery audit log.\n\n Records each webhook delivery attempt with status, response,\n and error information for debugging and auditing.\n\n Attributes:\n webhook: Reference to the Webhook DocType name\n event: The event that triggered the webhook\n status: Delivery status ('success' or 'failed')\n response_code: HTTP response status code\n response_body: HTTP response body (truncated)\n error: Error message if delivery failed\n timestamp: When the delivery was attempted\n\n**Source**: [webhook_log.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/webhook_log.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| webhook | str | \u2713 | Reference to Webhook name | minLen: 1 |\n| event | str | \u2713 | Event that triggered the webhook (e.g., 'doc.created') | minLen: 1 |\n| status | str | \u2713 | Delivery status: 'success' or 'failed | - |\n| response_code | int | \u2713 | HTTP response status code | - |\n| response_body | str | None | | HTTP response body (may be truncated) | - |\n| error | str | None | | Error message if delivery failed | - |\n| timestamp | datetime | | When the delivery was attempted | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Manager | | | \u2713 | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "WebhookLog"}} {"id": "doctype-file", "type": "doctype", "title": "DocType: File", "content": "# File\n\nFile attachment DocType.\n\n Stores metadata about uploaded files. Actual file content\n is stored via StorageAdapter (local, S3, GCS, etc.).\n\n Attributes:\n file_name: Original filename as uploaded\n file_url: Storage URL/path for retrieval\n file_size: Size in bytes\n content_type: MIME type (e.g., \"application/pdf\")\n attached_to_doctype: DocType this file is attached to\n attached_to_name: Document ID this file is attached to\n is_private: If True, requires authentication to access\n\n Example:\n file = File(\n file_name=\"report.pdf\",\n file_url=\"/files/2024/01/report-abc123.pdf\",\n file_size=51200,\n content_type=\"application/pdf\",\n is_private=True,\n )\n\n**Source**: [file.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/file.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| file_name | str | | Original filename | - |\n| file_url | str | | Storage URL/path | - |\n| file_size | int | | File size in bytes | - |\n| content_type | str | | MIME type | - |\n| attached_to_doctype | str | None | | DocType this file is attached to | - |\n| attached_to_name | str | None | | Document ID this file is attached to | - |\n| is_private | bool | | If True, requires authentication | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Guest | | | \u2713 | |\n| User | \u2713 | \u2713 | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "File"}} {"id": "doctype-session", "type": "doctype", "title": "DocType: Session", "content": "# Session\n\nDatabase-backed user session.\n\n Attributes:\n session_id: Unique session identifier (used as cookie value)\n user_id: User this session belongs to\n expires_at: When the session expires\n ip_address: Client IP address for security auditing\n user_agent: Client user agent for display\n\n Security:\n - session_id should be cryptographically random\n - Check expires_at before accepting session\n - Track ip_address/user_agent for security alerts\n\n**Source**: [session.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/session.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| session_id | str | | Unique session identifier | - |\n| user_id | str | | User this session belongs to | - |\n| expires_at | datetime | | Session expiration time | - |\n| ip_address | str | None | | Client IP address | - |\n| user_agent | str | None | | Client user agent string | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Session"}} {"id": "doctype-joblog", "type": "doctype", "title": "DocType: JobLog", "content": "# JobLog\n\nBackground job execution log.\n\n Records job execution status and results for monitoring,\n debugging, and audit purposes.\n\n Attributes:\n job_id: Unique job identifier from job queue\n job_name: Name of the job function\n status: Current status (queued/running/success/failed)\n enqueued_at: When the job was added to queue\n started_at: When the job started executing\n completed_at: When the job finished\n error: Error message if job failed\n result: Job result data if successful\n\n**Source**: [job_log.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/job_log.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| job_id | str | \u2713 | Unique job identifier from job queue | minLen: 1 |\n| job_name | str | \u2713 | Name of the job function | minLen: 1 |\n| status | str | \u2713 | Job status: queued, running, success, or failed | - |\n| enqueued_at | datetime | | When the job was added to queue | - |\n| started_at | datetime | None | | When the job started executing | - |\n| completed_at | datetime | None | | When the job finished (success or failure) | - |\n| error | str | None | | Error message if job failed | - |\n| result | dict[str, Any] | None | | Job result data if successful | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Employee | | | \u2713 | |\n| Manager | | | \u2713 | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "JobLog"}} {"id": "doctype-activitylog", "type": "doctype", "title": "DocType: ActivityLog", "content": "# ActivityLog\n\nActivity log entry DocType.\n\n Stores an immutable audit record of a user action on a document.\n Once created, activity logs should never be modified or deleted.\n\n Attributes:\n user_id: ID of the user who performed the action\n action: Type of action (\"create\", \"read\", \"update\", \"delete\")\n doctype: Name of the affected DocType\n document_id: ID of the affected document\n timestamp: When the action occurred (auto-set)\n changes: Field changes for updates (old/new values)\n metadata: Additional context (request_id, ip, user_agent)\n\n Example:\n log = ActivityLog(\n user_id=\"user-001\",\n action=\"create\",\n doctype=\"Todo\",\n document_id=\"TODO-001\",\n )\n\n**Source**: [activity_log.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/activity_log.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| user_id | str | \u2713 | ID of the user who performed the action | minLen: 1 |\n| action | str | \u2713 | Type of action: create, read, update, delete | pattern: `^(create|read|update|delete)$` |\n| doctype | str | \u2713 | Name of the affected DocType | minLen: 1 |\n| document_id | str | \u2713 | ID of the affected document | minLen: 1 |\n| timestamp | datetime | | When the action occurred (UTC) | - |\n| changes | dict[str, Any] | None | | Field changes for updates: {field: {old: x, new: y}} | - |\n| metadata | dict[str, Any] | None | | Additional context: request_id, ip, user_agent, etc. | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| All | | | \u2713 | |\n| System Manager | \u2713 | | \u2713 | |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "ActivityLog"}} {"id": "doctype-report", "type": "doctype", "title": "DocType: Report", "content": "# Report\n\nCQRS report configuration.\n\n Defines reports that support zero-cliff scalability from\n startup (Code Reports) to enterprise (Analytics with OLAP).\n\n Attributes:\n name: Unique report identifier\n report_type: Report execution mode (Code Report or Analytics Report)\n data_source: Data source adapter (SQL, Elastic, ClickHouse)\n query: Report query (SQL file path, SQL query, or Elastic DSL)\n enabled: Whether the report is active\n\n**Source**: [report.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/report.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| name | str | \u2713 | Unique report identifier | minLen: 1, maxLen: 255 |\n| report_type | str | \u2713 | Report execution mode: 'Code Report' (indie) or 'Analytics Report' (enterprise) | - |\n| data_source | str | None | | Data source adapter: SQL, Elastic, ClickHouse (for Analytics Reports) | - |\n| query | str | None | | Report query: SQL file path, SQL query, or Elastic DSL JSON | - |\n| enabled | bool | | Whether the report is active | - |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| Admin | \u2713 | \u2713 | \u2713 | \u2713 |\n| Employee | | | \u2713 | |\n| Manager | \u2713 | | \u2713 | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "Report"}} {"id": "doctype-workflowtransition", "type": "doctype", "title": "DocType: WorkflowTransition", "content": "# WorkflowTransition\n\nDefines an allowed transition in a workflow.\n\n Attributes:\n workflow: Name of the workflow this transition belongs to\n from_state: Source state name\n to_state: Destination state name\n action: Action name that triggers this transition\n allowed_roles: List of roles permitted to perform this transition\n condition: Optional Python expression to evaluate before allowing transition\n\n**Source**: [workflow_transition.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/workflow_transition.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| workflow | str | | Workflow name | - |\n| from_state | str | | Source state | - |\n| to_state | str | | Destination state | - |\n| action | str | | Transition action name | - |\n| allowed_roles | list[str] | | Roles allowed to perform this transition | - |\n| condition | str | None | | Optional Python expression for conditional transitions | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "WorkflowTransition"}} {"id": "doctype-printformat", "type": "doctype", "title": "DocType: PrintFormat", "content": "# PrintFormat\n\nPrint format configuration DocType.\n\n Stores print template configuration for a DocType.\n\n Attributes:\n name: Display name for the format\n doctype: Target DocType this format applies to\n template: Path to Jinja2 template file\n is_default: If True, this is the default format for the DocType\n css: Optional custom CSS for styling\n header_html: Optional custom header HTML\n footer_html: Optional custom footer HTML\n page_size: Page size for PDF (A4, Letter, etc.)\n orientation: Page orientation (portrait, landscape)\n\n Example:\n format = PrintFormat(\n name=\"Invoice Pro Forma\",\n doctype=\"Invoice\",\n template=\"invoice_proforma.html\",\n )\n\n**Source**: [print_format.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/doctypes/print_format.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| name | str | \u2713 | Display name for the print format | minLen: 1, maxLen: 255 |\n| doctype | str | \u2713 | Target DocType this format applies to | minLen: 1 |\n| template | str | \u2713 | Path to Jinja2 template file | minLen: 1 |\n| is_default | bool | | If True, this is the default format for the DocType | - |\n| css | str | None | | Optional custom CSS for styling | - |\n| header_html | str | None | | Optional custom header HTML | - |\n| footer_html | str | None | | Optional custom footer HTML | - |\n| page_size | str | | Page size for PDF (A4, Letter, Legal) | pattern: `^(A4|Letter|Legal|A3|A5)$` |\n| orientation | str | | Page orientation (portrait, landscape) | pattern: `^(portrait|landscape)$` |\n\n## Permissions\n\n| Role | Create | Delete | Read | Write |\n|------|------|------|------|------|\n| All | | | \u2713 | |\n| System Manager | \u2713 | \u2713 | | \u2713 |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "PrintFormat"}} {"id": "doctype-namingcounter", "type": "doctype", "title": "DocType: NamingCounter", "content": "# NamingCounter\n\nCounter storage for naming series.\n\n Stores the current counter value for each prefix, enabling\n persistent and queryable counter management.\n\n Example:\n # Counter for INV-2026- prefix\n counter = NamingCounter(prefix=\"INV-2026-\", current=42)\n\n # Next invoice will be INV-2026-0043\n\n Note:\n Uses optimistic updates - no SELECT FOR UPDATE needed.\n On conflict, retry with incremented value.\n\n**Source**: [naming_counter.py](file:///builds/castlecraft/framework-m/libs/framework-m-core/src/framework_m_core/domain/naming_counter.py)\n\n## Fields\n\n| Field | Type | Required | Description | Validators |\n|-------|------|----------|-------------|------------|\n| prefix | str | | Naming series prefix | - |\n| current | int | | Current counter value | - |\n\n## Configuration\n\n| Setting | Value |\n|---------|-------|\n| Submittable | `False` |\n| Track Changes | `True` |\n\n## Controller\n\nController hooks are implemented in `*_controller.py` files.\nAvailable lifecycle hooks:\n\n- `validate()` - Called before save, raise exceptions for validation errors\n- `before_insert()` - Called before inserting a new document\n- `after_insert()` - Called after successfully inserting\n- `before_save()` - Called before saving (insert or update)\n- `after_save()` - Called after saving\n- `before_delete()` - Called before deleting\n- `after_delete()` - Called after deleting\n", "metadata": {"module": "framework_m_studio.discovery", "name": "NamingCounter"}} {"id": "file-docs-intro.md", "type": "doc", "title": "Document: docs/intro.md", "content": "---\nsidebar_position: 1\n---\n\n# Introduction\n\n[](https://gitlab.com/castlecraft/framework-m/-/pipelines)\n[](https://www.python.org/downloads/)\n[](https://opensource.org/licenses/Apache-2.0)\n[](https://gitlab.com/castlecraft/framework-m)\n\nWelcome to the **Framework M** documentation.\n\n> **Build once. Scale forever.**\n\nFramework M is a modular, metadata-driven full-stack framework designed for building scalable enterprise applications. It bridges the gap between rapid development velocity and enterprise-grade architecture.\n\n:::tip Core Philosophical Pillars\nThe **\"M\"** in Framework M represents our three architectural foundations:\n\n- **Modular**: Built on **Hexagonal Architecture** (Ports & Adapters). Build a **Modular Monolith** for velocity and transparently decompose into **Microservices** for scale without a rewrite.\n- **Multi-Tenant**: Native, first-class support for multi-tenancy is baked into every layer\u2014from the database to the API.\n- **Metadata-Driven**: Application behavior is defined by **DocTypes** (metadata) to accelerate development. This enables automatic CRUD, UI, and workflows with modern type safety.\n:::\n\n## Why Framework M?\n\nBatteries-included frameworks deliver incredible initial velocity, but often lead to a \"productivity cliff\" when scale, enterprise integration, or complex deployment requirements arise.\n\nFramework M is designed to provide **Zero Cliff Architecture**. You get the same rapid development experience\u2014DocTypes, automatic CRUD, permissions, workflows\u2014but built on enterprise-grade foundations from day one.\n\n## Quick Navigation\n\n- **[Quick Start](user/getting-started.md)**: Get up and running in minutes.\n- **[Developer Guide](developer/index.md)**: Deep dive into the framework architecture.\n- **[Architecture](developer/architecture.md)**: Understand Hexagonal Architecture & Ports/Adapters.\n- **[Defining DocTypes](developer/defining-doctypes.md)**: Learn about metadata-driven development.\n- **[ADRs](adr/)**: Understand the \"why\" behind our architecture decisions.\n- **[Checklists](/checklists/)**: Track the implementation progress of the framework.\n\n---\n\n*For technical documentation and deployment details, please refer to the [README](https://gitlab.com/castlecraft/framework-m).*\n", "metadata": {"path": "docs/intro.md"}} {"id": "file-docs-developer-frontend-testing.md", "type": "doc", "title": "Document: docs/developer/frontend-testing.md", "content": "---\ntitle: Frontend Testing\nsidebar_position: 11\n---\n\n# Frontend Testing Guide\n\nComplete testing documentation for the Framework M frontend application.\n\n## Table of Contents\n\n- [Overview](#overview)\n- [Test Infrastructure](#test-infrastructure)\n- [Unit Tests](#unit-tests)\n- [Integration Tests](#integration-tests)\n- [E2E Tests](#e2e-tests)\n- [Running Tests](#running-tests)\n- [Writing New Tests](#writing-new-tests)\n- [Best Practices](#best-practices)\n- [Troubleshooting](#troubleshooting)\n\n## Overview\n\nThe frontend uses a comprehensive testing strategy with three layers:\n\n1. **Unit Tests** - Test individual components in isolation\n2. **Integration Tests** - Test component interactions and workflows\n3. **E2E Tests** - Test complete user workflows across browsers\n\n### Technology Stack\n\n- **Test Runner**: [Vitest](https://vitest.dev/) - Vite-native test runner\n- **Component Testing**: [@testing-library/react](https://testing-library.com/react) - User-centric testing utilities\n- **User Interactions**: [@testing-library/user-event](https://testing-library.com/docs/user-event/intro) - Realistic user interactions\n- **Assertions**: [@testing-library/jest-dom](https://github.com/testing-library/jest-dom) - DOM matchers\n- **DOM Environment**: [happy-dom](https://github.com/capricorn86/happy-dom) - Fast DOM implementation\n- **E2E Testing**: [Playwright](https://playwright.dev/) - Cross-browser automation\n\n## Test Infrastructure\n\n### Configuration Files\n\n#### `vitest.config.ts`\n\n```typescript\nimport { defineConfig } from \"vitest/config\";\nimport react from \"@vitejs/plugin-react\";\n\nexport default defineConfig({\n plugins: [react()],\n test: {\n environment: \"happy-dom\",\n globals: true,\n setupFiles: [\"./src/setupTests.ts\"],\n css: true,\n coverage: {\n provider: \"v8\",\n reporter: [\"text\", \"json\", \"html\"],\n },\n },\n});\n```\n\n#### `src/setupTests.ts`\n\nGlobal test setup that runs before all tests:\n\n- Imports `@testing-library/jest-dom` matchers\n- Mocks `window.matchMedia` (for theme detection)\n- Mocks `localStorage` and `sessionStorage`\n- Mocks `IntersectionObserver` and `ResizeObserver`\n- Auto-cleanup after each test\n\n#### `playwright.config.ts`\n\nE2E test configuration:\n\n- Tests in `tests/e2e/` directory\n- Runs against `http://localhost:5173`\n- Auto-starts dev server\n- Tests on Chromium, Firefox, and WebKit\n- Screenshots and videos on failure\n\n## Unit Tests\n\n### Location\n\nUnit tests are colocated with components in `__tests__` directories:\n\n```\nsrc/\n\u251c\u2500\u2500 components/\n\u2502 \u251c\u2500\u2500 __tests__/\n\u2502 \u2502 \u251c\u2500\u2500 ThemeToggle.test.tsx\n\u2502 \u2502 \u251c\u2500\u2500 AutoForm.test.tsx\n\u2502 \u2502 \u2514\u2500\u2500 AutoTable.test.tsx\n\u2502 \u251c\u2500\u2500 ThemeToggle.tsx\n\u2502 \u2514\u2500\u2500 ...\n```\n\n### Example: Component Test\n\n```typescript\nimport { describe, it, expect } from \"vitest\";\nimport { render, screen } from \"@testing-library/react\";\nimport { userEvent } from \"@testing-library/user-event\";\nimport { ThemeToggle } from \"../ThemeToggle\";\nimport { ThemeProvider } from \"../../contexts/ThemeContext\";\n\ndescribe(\"ThemeToggle\", () => {\n it(\"toggles theme when clicked\", async () => {\n const user = userEvent.setup();\n\n render(\nCurrent theme: {theme}
\n \n \n \n{error.message}\n