{"id":31322773,"url":"https://github.com/ahmtydn/supabase_annotations","last_synced_at":"2026-05-16T17:06:20.730Z","repository":{"id":314331788,"uuid":"1055089084","full_name":"ahmtydn/supabase_annotations","owner":"ahmtydn","description":"A code generator for creating Supabase/PostgreSQL database schemas from Dart model classes. Supports RLS policies, indexes, foreign keys, and schema validation.","archived":false,"fork":false,"pushed_at":"2025-09-11T22:23:11.000Z","size":21017,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-11T22:31:50.115Z","etag":null,"topics":["code-gen","dart-package","flutter-package","generator","postgres","pub-dev","schema-generator","sql-generator"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/supabase_annotations","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahmtydn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-11T18:47:47.000Z","updated_at":"2025-09-11T22:23:14.000Z","dependencies_parsed_at":"2025-09-11T22:31:52.473Z","dependency_job_id":"a85596c7-d42d-4b81-85d0-12f43ff92e82","html_url":"https://github.com/ahmtydn/supabase_annotations","commit_stats":null,"previous_names":["ahmtydn/supabase_annotations"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/ahmtydn/supabase_annotations","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmtydn%2Fsupabase_annotations","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmtydn%2Fsupabase_annotations/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmtydn%2Fsupabase_annotations/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmtydn%2Fsupabase_annotations/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahmtydn","download_url":"https://codeload.github.com/ahmtydn/supabase_annotations/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahmtydn%2Fsupabase_annotations/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276966649,"owners_count":25736835,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-25T02:00:09.612Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-gen","dart-package","flutter-package","generator","postgres","pub-dev","schema-generator","sql-generator"],"created_at":"2025-09-25T19:13:42.979Z","updated_at":"2025-09-25T19:13:47.737Z","avatar_url":"https://github.com/ahmtydn.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚀 Supabase Annotations\n\n[![pub package](https://img.shields.io/pub/v/supabase_annotations.svg)](https://pub.dev/packages/supabase_annotations)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![GitHub stars](https://img.shields.io/github/stars/ahmtydn/supabase_annotations.svg?style=social\u0026label=Star)](https://github.com/ahmtydn/supabase_annotations)\n\nA powerful, type-safe code generator for creating **Supabase/PostgreSQL** database schemas from Dart model classes. Build production-ready database schemas with **Row Level Security (RLS)**, **indexes**, **foreign keys**, **migrations**, and **table partitioning** - all from your Dart code.\n\n---\n\n## 📚 Table of Contents\n\n- [✨ Features](#-features)\n- [🚀 Quick Start](#-quick-start)\n- [📖 Core Annotations](#-core-annotations)\n- [🔧 Configuration](#-configuration)\n- [🗄️ Column Types \u0026 Constraints](#️-column-types--constraints)\n- [🔐 Security \u0026 RLS Policies](#-security--rls-policies)\n- [⚡ Performance \u0026 Indexing](#-performance--indexing)\n- [🔄 Migration Support](#-migration-support)\n- [🎯 Advanced Examples](#-advanced-examples)\n- [📝 Best Practices](#-best-practices)\n- [🛠️ Development](#️-development)\n- [🤝 Contributing](#-contributing)\n- [📄 License](#-license)\n\n---\n\n## ✨ Features\n\n### 🏗️ **Schema Generation**\n- **Type-Safe SQL Generation** - Convert Dart classes to PostgreSQL schemas\n- **Full PostgreSQL Support** - All column types, constraints, and features\n- **Automatic Documentation** - Generate SQL comments from Dart documentation\n\n### 🔐 **Security First**\n- **Row Level Security (RLS)** - Declarative RLS policy generation\n- **Fine-Grained Permissions** - Control access at the row and column level\n- **Authentication Integration** - Built-in Supabase auth helpers\n\n### ⚡ **Performance Optimization**\n- **Smart Indexing** - Automatic and custom index generation\n- **Query Optimization** - Composite indexes and partial indexes\n- **Table Partitioning** - Range and hash partitioning support\n\n### 🔄 **Migration \u0026 Evolution**\n- **Safe Schema Evolution** - Multiple migration strategies\n- **Zero-Downtime Updates** - ADD COLUMN and ALTER TABLE support\n- **Rollback Support** - Safe migration with fallback options\n\n### 🎯 **Developer Experience**\n- **IDE Integration** - Full IntelliSense and code completion\n- **Comprehensive Validation** - Catch errors at build time\n- **Rich Documentation** - Inline help and examples\n\n---\n\n## 🚀 Quick Start\n\n### 1️⃣ Installation\n\nAdd to your `pubspec.yaml`:\n\n```yaml\ndependencies:\n  supabase_annotations: ^1.1.1\n\ndev_dependencies:\n  build_runner: ^2.4.8\n  source_gen: ^1.5.0\n```\n\n### 2️⃣ Configuration\n\nCreate `build.yaml` in your project root:\n\n```yaml\ntargets:\n  $default:\n    builders:\n      supabase_annotations|schema_builder:\n        enabled: true\n        generate_for:\n          include:\n            - lib/**.dart\n            - example/**.dart\n          exclude:\n            - lib/**.g.dart\n            - lib/**.schema.dart\n        options:\n          # 🔄 Migration Strategy\n          migration_mode: 'createOrAlter'        # Safe schema evolution\n          enable_column_adding: true             # Add missing columns\n          generate_do_blocks: true               # PostgreSQL DO blocks\n          \n          # 🔐 Security Configuration\n          enable_rls_by_default: false           # RLS on all tables\n          \n          # 📝 Code Generation\n          generate_comments: true                # Include documentation\n          validate_schema: true                  # Schema validation\n          format_sql: true                      # Format output\n```\n\n### 3️⃣ Define Your Model\n\n```dart\nimport 'package:supabase_annotations/supabase_annotations.dart';\n\n@DatabaseTable(\n  name: 'users',\n  enableRLS: true,\n  comment: 'Application users with authentication',\n)\n@RLSPolicy(\n  name: 'users_own_data',\n  type: RLSPolicyType.all,\n  condition: 'auth.uid() = id',\n)\n@DatabaseIndex(\n  name: 'users_email_idx',\n  columns: ['email'],\n  isUnique: true,\n)\nclass User {\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isPrimaryKey: true,\n    defaultValue: DefaultValue.generateUuid,\n  )\n  String? id;\n\n  @DatabaseColumn(\n    type: ColumnType.text,\n    isUnique: true,\n    isNullable: false,\n  )\n  late String email;\n\n  @DatabaseColumn(\n    type: ColumnType.varchar(100),\n    isNullable: false,\n  )\n  late String fullName;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n  )\n  late DateTime createdAt;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n  )\n  late DateTime updatedAt;\n}\n```\n\n### 4️⃣ Generate Schema\n\n```bash\n# Generate SQL schema files\ndart run build_runner build\n\n# Watch for changes and regenerate\ndart run build_runner watch\n```\n\n### 5️⃣ Generated Output\n\n```sql\n-- 📄 Generated: lib/models/user.schema.sql\n\n-- 🏗️ Create table with RLS enabled\nCREATE TABLE IF NOT EXISTS users (\n  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n  email TEXT UNIQUE NOT NULL,\n  full_name VARCHAR(100) NOT NULL,\n  created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,\n  updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP\n);\n\n-- 🔐 Enable Row Level Security\nALTER TABLE users ENABLE ROW LEVEL SECURITY;\n\n-- 🛡️ Create RLS policy\nCREATE POLICY users_own_data ON users \n  FOR ALL \n  USING (auth.uid() = id);\n\n-- ⚡ Create performance indexes\nCREATE UNIQUE INDEX users_email_idx ON users(email);\n\n-- 📝 Add table comment\nCOMMENT ON TABLE users IS 'Application users with authentication';\n```\n\n---\n\n## 📖 Core Annotations\n\n### 🏗️ `@DatabaseTable`\n\nConfigure table-level settings:\n\n```dart\n@DatabaseTable(\n  name: 'custom_table_name',      // 📝 Custom table name (optional)\n  enableRLS: true,                // 🔐 Row Level Security\n  comment: 'Table description',   // 📄 Documentation\n  partitionBy: RangePartition(    // 📊 Table partitioning\n    columns: ['created_at']\n  ),\n)\nclass MyTable { }\n```\n\n### 🏷️ `@DatabaseColumn`\n\nDefine column properties:\n\n```dart\n@DatabaseColumn(\n  name: 'custom_column_name',     // 📝 Custom column name\n  type: ColumnType.varchar(255),  // 🎯 PostgreSQL type\n  isNullable: false,              // ❌ NOT NULL constraint\n  isPrimaryKey: true,             // 🔑 Primary key\n  isUnique: true,                 // ⭐ Unique constraint\n  defaultValue: DefaultValue.currentTimestamp,  // 🔄 Default value\n  comment: 'Column description',  // 📄 Documentation\n  checkConstraints: ['value \u003e 0'], // ✅ CHECK constraints\n)\nlate String myField;\n```\n\n### 🔗 `@ForeignKey`\n\nDefine relationships:\n\n```dart\n@ForeignKey(\n  table: 'users',                          // 🎯 Referenced table\n  column: 'id',                           // 🔗 Referenced column\n  onDelete: ForeignKeyAction.cascade,     // 🗑️ Delete behavior\n  onUpdate: ForeignKeyAction.restrict,    // 🔄 Update behavior\n)\n@DatabaseColumn(type: ColumnType.uuid)\nlate String userId;\n```\n\n### ⚡ `@DatabaseIndex`\n\nOptimize performance:\n\n```dart\n// 📊 Composite index on table\n@DatabaseIndex(\n  name: 'user_status_created_idx',\n  columns: ['status', 'created_at'],\n  type: IndexType.btree,\n  isUnique: false,\n  where: \"status != 'deleted'\",  // 🎯 Partial index\n)\nclass User { }\n\n// 🔍 Single column index\n@DatabaseIndex(type: IndexType.hash)\n@DatabaseColumn(type: ColumnType.text)\nlate String status;\n```\n\n### 🛡️ `@RLSPolicy`\n\nSecure your data:\n\n```dart\n@RLSPolicy(\n  name: 'user_read_own',                    // 📝 Policy name\n  type: RLSPolicyType.select,              // 🎯 Operation type\n  condition: 'auth.uid() = user_id',       // 🔐 Access condition\n  roles: ['authenticated'],                // 👥 Database roles\n  comment: 'Users can read their own data', // 📄 Documentation\n)\nclass UserData { }\n```\n\n---\n\n## 🔧 Configuration\n\n### 📋 Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `migration_mode` | string | `'createOnly'` | Migration strategy |\n| `enable_column_adding` | bool | `true` | Add missing columns |\n| `generate_do_blocks` | bool | `true` | Use DO blocks for safety |\n| `enable_rls_by_default` | bool | `false` | RLS on all tables |\n| `add_timestamps` | bool | `false` | Auto-add timestamps |\n| `use_explicit_nullability` | bool | `false` | Explicit NULL/NOT NULL |\n| `generate_comments` | bool | `true` | Include documentation |\n| `validate_schema` | bool | `true` | Schema validation |\n| `format_sql` | bool | `true` | Format SQL output |\n\n### 🎯 Environment-Specific Configurations\n\n**🔧 Development Setup:**\n```yaml\noptions:\n  migration_mode: 'createOrAlter'    # Safe evolution\n  enable_rls_by_default: false       # Easier testing\n  generate_comments: true            # Full docs\n  validate_schema: true              # Catch errors\n  format_sql: true                  # Readable output\n```\n\n**🚀 Production Setup:**\n```yaml\noptions:\n  migration_mode: 'createOrAlter'    # Safe migrations\n  enable_column_adding: true         # Allow evolution\n  generate_do_blocks: true           # Extra safety\n  validate_schema: true              # Strict validation\n  format_sql: true                  # Clean output\n```\n\n**🤖 CI/CD Pipeline:**\n```yaml\noptions:\n  migration_mode: 'createOnly'       # Standard creation\n  validate_schema: true              # Fail on errors\n  generate_comments: false           # Minimal output\n  format_sql: true                  # Consistent format\n```\n\n---\n\n## 🗄️ Column Types \u0026 Constraints\n\n### 📊 PostgreSQL Column Types\n\n#### 📝 Text Types\n```dart\nColumnType.text                    // TEXT\nColumnType.varchar(255)            // VARCHAR(255)\nColumnType.char(10)               // CHAR(10)\n```\n\n#### 🔢 Numeric Types\n```dart\nColumnType.integer                 // INTEGER\nColumnType.bigint                 // BIGINT\nColumnType.decimal(10, 2)         // DECIMAL(10,2)\nColumnType.real                   // REAL\nColumnType.doublePrecision        // DOUBLE PRECISION\nColumnType.serial                 // SERIAL\nColumnType.bigserial             // BIGSERIAL\n```\n\n#### 📅 Date/Time Types\n```dart\nColumnType.timestamp              // TIMESTAMP\nColumnType.timestampWithTimeZone  // TIMESTAMPTZ\nColumnType.date                   // DATE\nColumnType.time                   // TIME\nColumnType.interval              // INTERVAL\n```\n\n#### 🎯 Special Types\n```dart\nColumnType.uuid                   // UUID\nColumnType.boolean               // BOOLEAN\nColumnType.json                  // JSON\nColumnType.jsonb                 // JSONB\nColumnType.bytea                 // BYTEA\nColumnType.inet                  // INET\nColumnType.macaddr              // MACADDR\nColumnType.point                // POINT\nColumnType.array(ColumnType.text) // TEXT[]\n```\n\n### 🔄 Default Values\n\n```dart\n// 📄 Literal values\nDefaultValue.none                 // NULL\nDefaultValue.zero                // 0\nDefaultValue.one                 // 1\nDefaultValue.emptyString         // ''\nDefaultValue.emptyArray          // ARRAY[]\nDefaultValue.emptyObject         // '{}'\n\n// ⚡ Functions\nDefaultValue.currentTimestamp    // CURRENT_TIMESTAMP\nDefaultValue.currentDate         // CURRENT_DATE\nDefaultValue.generateUuid        // gen_random_uuid()\nDefaultValue.autoIncrement       // nextval(sequence)\n\n// 🏭 Factory methods\nDefaultValue.string('value')     // 'value'\nDefaultValue.number(42)          // 42\nDefaultValue.boolean(true)       // true\nDefaultValue.expression('NOW()') // Custom expression\n```\n\n### ✅ Constraints\n\n```dart\n@DatabaseColumn(\n  // 🔑 Primary key\n  isPrimaryKey: true,\n  \n  // ⭐ Unique constraint\n  isUnique: true,\n  \n  // ❌ NOT NULL constraint\n  isNullable: false,\n  \n  // ✅ CHECK constraints\n  checkConstraints: [\n    'length(email) \u003e 0',\n    'email ~* \\'^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\$\\'',\n  ],\n)\nlate String email;\n```\n\n---\n\n## 🔐 Security \u0026 RLS Policies\n\n### 🛡️ RLS Policy Types\n\n```dart\nRLSPolicyType.all         // 🌟 All operations (CRUD)\nRLSPolicyType.select      // 👁️ Read operations only\nRLSPolicyType.insert      // ➕ Insert operations only\nRLSPolicyType.update      // ✏️ Update operations only\nRLSPolicyType.delete      // 🗑️ Delete operations only\n```\n\n### 🎯 Common RLS Patterns\n\n#### 👤 User Owns Data\n```dart\n@RLSPolicy(\n  name: 'users_own_data',\n  type: RLSPolicyType.all,\n  condition: 'auth.uid() = user_id',\n)\n```\n\n#### 🏢 Multi-tenant Isolation\n```dart\n@RLSPolicy(\n  name: 'tenant_isolation',\n  type: RLSPolicyType.all,\n  condition: 'tenant_id = auth.jwt() -\u003e\u003e \"tenant_id\"',\n)\n```\n\n#### 👥 Role-based Access\n```dart\n@RLSPolicy(\n  name: 'admin_full_access',\n  type: RLSPolicyType.all,\n  condition: 'auth.jwt() -\u003e\u003e \"role\" = \"admin\"',\n  roles: ['authenticated'],\n)\n\n@RLSPolicy(\n  name: 'user_read_only',\n  type: RLSPolicyType.select,\n  condition: 'auth.jwt() -\u003e\u003e \"role\" = \"user\"',\n  roles: ['authenticated'],\n)\n```\n\n#### 🕒 Time-based Access\n```dart\n@RLSPolicy(\n  name: 'active_records_only',\n  type: RLSPolicyType.select,\n  condition: 'expires_at \u003e NOW() AND is_active = true',\n)\n```\n\n---\n\n## ⚡ Performance \u0026 Indexing\n\n### 🔍 Index Types\n\n```dart\nIndexType.btree       // 🌳 B-tree (default, general purpose)\nIndexType.hash        // #️⃣ Hash (equality only)\nIndexType.gin         // 🔍 GIN (JSON, arrays, full-text)\nIndexType.gist        // 🎯 GiST (geometric, full-text)\nIndexType.spgist      // 📊 SP-GiST (space-partitioned)\nIndexType.brin        // 📈 BRIN (large ordered tables)\n```\n\n### 📊 Index Strategies\n\n#### 🔍 Single Column Index\n```dart\n@DatabaseIndex(type: IndexType.btree)\n@DatabaseColumn(type: ColumnType.text)\nlate String status;\n```\n\n#### 📈 Composite Index\n```dart\n@DatabaseIndex(\n  name: 'user_activity_idx',\n  columns: ['user_id', 'created_at', 'activity_type'],\n  type: IndexType.btree,\n)\n```\n\n#### 🎯 Partial Index\n```dart\n@DatabaseIndex(\n  name: 'active_users_idx',\n  columns: ['email'],\n  where: \"status = 'active' AND deleted_at IS NULL\",\n)\n```\n\n#### 🔍 Expression Index\n```dart\n@DatabaseIndex(\n  name: 'user_search_idx',\n  expression: \"to_tsvector('english', name || ' ' || email)\",\n  type: IndexType.gin,\n)\n```\n\n#### 📱 JSON Index\n```dart\n@DatabaseIndex(\n  name: 'metadata_search_idx',\n  expression: \"(metadata -\u003e 'tags')\",\n  type: IndexType.gin,\n)\n```\n\n---\n\n## 🔄 Migration Support\n\n### 🎯 Migration Modes\n\n| Mode | Description | Use Case |\n|------|-------------|----------|\n| `createOnly` | Standard CREATE TABLE | 🆕 New projects |\n| `createIfNotExists` | CREATE TABLE IF NOT EXISTS | 🔒 Safe creation |\n| `createOrAlter` | CREATE + ALTER for new columns | 🔄 Schema evolution |\n| `alterOnly` | Only ALTER TABLE statements | 🛠️ Existing schemas |\n| `dropAndRecreate` | DROP and CREATE | 🧪 Development only |\n\n### 📝 Migration Examples\n\n#### 🆕 Adding New Column\n```dart\n// Add this field to existing User class\n@DatabaseColumn(\n  type: ColumnType.integer,\n  defaultValue: DefaultValue.zero,\n)\nint? age;\n```\n\n**Generated Migration:**\n```sql\n-- 🔄 Safe column addition\nDO $$\nBEGIN\n  IF NOT EXISTS (\n    SELECT 1 FROM information_schema.columns\n    WHERE table_name = 'users' AND column_name = 'age'\n  ) THEN\n    ALTER TABLE users ADD COLUMN age INTEGER DEFAULT 0;\n  END IF;\nEND $$;\n```\n\n#### 🔗 Adding Foreign Key\n```dart\n// Add relationship to existing table\n@ForeignKey(\n  table: 'companies',\n  column: 'id',\n  onDelete: ForeignKeyAction.setNull,\n)\n@DatabaseColumn(type: ColumnType.uuid)\nString? companyId;\n```\n\n**Generated Migration:**\n```sql\n-- 🔗 Safe foreign key addition\nDO $$\nBEGIN\n  IF NOT EXISTS (\n    SELECT 1 FROM information_schema.columns\n    WHERE table_name = 'users' AND column_name = 'company_id'\n  ) THEN\n    ALTER TABLE users ADD COLUMN company_id UUID;\n    ALTER TABLE users ADD CONSTRAINT users_company_id_fkey \n      FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL;\n  END IF;\nEND $$;\n```\n\n### 🛡️ Safe Migration Practices\n\n```yaml\n# 🎯 Recommended production configuration\noptions:\n  migration_mode: 'createOrAlter'     # Safe evolution\n  enable_column_adding: true          # Allow new columns\n  generate_do_blocks: true            # Extra safety checks\n  validate_schema: true               # Comprehensive validation\n```\n\n---\n\n## 🎯 Advanced Examples\n\n### 🏢 Multi-tenant SaaS Application\n\n```dart\n@DatabaseTable(\n  name: 'documents',\n  enableRLS: true,\n  comment: 'Multi-tenant document storage',\n)\n@RLSPolicy(\n  name: 'tenant_isolation',\n  type: RLSPolicyType.all,\n  condition: 'tenant_id = auth.jwt() -\u003e\u003e \"tenant_id\"',\n)\n@DatabaseIndex(\n  name: 'documents_tenant_created_idx',\n  columns: ['tenant_id', 'created_at'],\n)\n@DatabaseIndex(\n  name: 'documents_search_idx',\n  expression: \"to_tsvector('english', title || ' ' || content)\",\n  type: IndexType.gin,\n)\nclass Document {\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isPrimaryKey: true,\n    defaultValue: DefaultValue.generateUuid,\n  )\n  String? id;\n\n  @ForeignKey(\n    table: 'tenants',\n    column: 'id',\n    onDelete: ForeignKeyAction.cascade,\n  )\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isNullable: false,\n  )\n  late String tenantId;\n\n  @DatabaseColumn(\n    type: ColumnType.text,\n    isNullable: false,\n    checkConstraints: ['length(title) \u003e 0'],\n  )\n  late String title;\n\n  @DatabaseColumn(type: ColumnType.text)\n  String? content;\n\n  @DatabaseColumn(\n    type: ColumnType.jsonb,\n    defaultValue: DefaultValue.emptyObject,\n  )\n  Map\u003cString, dynamic\u003e? metadata;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n  )\n  late DateTime createdAt;\n}\n```\n\n### 🛒 E-commerce System\n\n```dart\n@DatabaseTable(\n  name: 'orders',\n  enableRLS: true,\n  comment: 'Customer orders with audit trail',\n)\n@RLSPolicy(\n  name: 'customers_own_orders',\n  type: RLSPolicyType.select,\n  condition: 'customer_id = auth.uid()',\n)\n@RLSPolicy(\n  name: 'staff_manage_orders',\n  type: RLSPolicyType.all,\n  condition: 'auth.jwt() -\u003e\u003e \"role\" IN (\"admin\", \"staff\")',\n)\n@DatabaseIndex(\n  name: 'orders_customer_status_idx',\n  columns: ['customer_id', 'status', 'created_at'],\n)\n@DatabaseIndex(\n  name: 'orders_total_idx',\n  columns: ['total_amount'],\n  where: \"status != 'cancelled'\",\n)\nclass Order {\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isPrimaryKey: true,\n    defaultValue: DefaultValue.generateUuid,\n  )\n  String? id;\n\n  @ForeignKey(\n    table: 'customers',\n    column: 'id',\n    onDelete: ForeignKeyAction.restrict,\n  )\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isNullable: false,\n  )\n  late String customerId;\n\n  @DatabaseColumn(\n    type: ColumnType.varchar(20),\n    defaultValue: DefaultValue.string('pending'),\n    checkConstraints: [\n      \"status IN ('pending', 'processing', 'shipped', 'delivered', 'cancelled')\"\n    ],\n  )\n  late String status;\n\n  @DatabaseColumn(\n    type: ColumnType.decimal(10, 2),\n    isNullable: false,\n    checkConstraints: ['total_amount \u003e= 0'],\n  )\n  late double totalAmount;\n\n  @DatabaseColumn(\n    type: ColumnType.jsonb,\n    comment: 'Order line items with product details',\n  )\n  List\u003cMap\u003cString, dynamic\u003e\u003e? items;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n  )\n  late DateTime createdAt;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n  )\n  late DateTime updatedAt;\n}\n```\n\n### 📊 Analytics \u0026 Logging\n\n```dart\n@DatabaseTable(\n  name: 'events',\n  comment: 'Application event tracking',\n  partitionBy: RangePartition(columns: ['created_at']),\n)\n@DatabaseIndex(\n  name: 'events_type_created_idx',\n  columns: ['event_type', 'created_at'],\n)\n@DatabaseIndex(\n  name: 'events_user_session_idx',\n  columns: ['user_id', 'session_id'],\n  where: \"user_id IS NOT NULL\",\n)\n@DatabaseIndex(\n  name: 'events_properties_idx',\n  expression: \"(properties -\u003e 'category')\",\n  type: IndexType.gin,\n)\nclass Event {\n  @DatabaseColumn(\n    type: ColumnType.uuid,\n    isPrimaryKey: true,\n    defaultValue: DefaultValue.generateUuid,\n  )\n  String? id;\n\n  @DatabaseColumn(\n    type: ColumnType.varchar(50),\n    isNullable: false,\n  )\n  late String eventType;\n\n  @DatabaseColumn(type: ColumnType.uuid)\n  String? userId;\n\n  @DatabaseColumn(type: ColumnType.uuid)\n  String? sessionId;\n\n  @DatabaseColumn(\n    type: ColumnType.jsonb,\n    defaultValue: DefaultValue.emptyObject,\n  )\n  Map\u003cString, dynamic\u003e? properties;\n\n  @DatabaseColumn(\n    type: ColumnType.inet,\n    comment: 'Client IP address',\n  )\n  String? ipAddress;\n\n  @DatabaseColumn(\n    type: ColumnType.text,\n    comment: 'User agent string',\n  )\n  String? userAgent;\n\n  @DatabaseColumn(\n    type: ColumnType.timestampWithTimeZone,\n    defaultValue: DefaultValue.currentTimestamp,\n    isNullable: false,\n  )\n  late DateTime createdAt;\n}\n```\n\n---\n\n## 📝 Best Practices\n\n### 🏗️ Schema Design\n\n#### ✅ **DO:**\n- Use descriptive, meaningful names\n- Follow PostgreSQL naming conventions (snake_case)\n- Keep names under 63 characters\n- Add comprehensive comments and documentation\n- Use appropriate column types for your data\n\n#### ❌ **DON'T:**\n- Use reserved keywords as names\n- Create overly complex nested structures\n- Forget to add indexes on frequently queried columns\n- Skip validation constraints\n\n### 🔐 Security Guidelines\n\n#### ✅ **DO:**\n- Always enable RLS on tables with sensitive data\n- Use specific, restrictive policy conditions\n- Test policies thoroughly with different user roles\n- Document security requirements and assumptions\n- Use parameterized conditions to prevent injection\n\n#### ❌ **DON'T:**\n- Rely solely on application-level security\n- Create overly permissive policies\n- Forget to test edge cases in policy conditions\n- Hardcode user IDs in policies\n\n### ⚡ Performance Optimization\n\n#### ✅ **DO:**\n- Add indexes on frequently queried columns\n- Use composite indexes for multi-column queries\n- Consider partial indexes for filtered queries\n- Use appropriate index types for your use case\n- Monitor query performance regularly\n\n#### ❌ **DON'T:**\n- Create too many indexes (impacts write performance)\n- Index every column \"just in case\"\n- Forget to maintain statistics on large tables\n- Ignore query execution plans\n\n### 🔄 Migration Management\n\n#### ✅ **DO:**\n- Use migration modes for schema evolution\n- Test migrations on staging data first\n- Plan for rollback scenarios\n- Document breaking changes thoroughly\n- Use `createOrAlter` mode for production\n\n#### ❌ **DON'T:**\n- Drop tables or columns without backup\n- Skip testing migrations\n- Apply untested migrations to production\n- Forget to version your schema changes\n\n---\n\n## 🛠️ Development\n\n### 🚀 Getting Started\n\n```bash\n# Clone the repository\ngit clone https://github.com/ahmtydn/supabase_annotations.git\ncd supabase_annotations\n\n# Install dependencies\ndart pub get\n\n# Run tests\ndart test\n\n# Run analysis\ndart analyze\n\n# Generate documentation\ndart doc\n```\n\n### 🧪 Running Examples\n\n```bash\n# Navigate to examples\ncd example\n\n# Generate schemas for all examples\ndart run build_runner build\n\n# View generated SQL files\nls lib/*.schema.sql\n```\n\n### 🔍 Project Structure\n\n```\nlib/\n├── builder.dart                 # Build configuration\n├── supabase_annotations.dart    # Public API\n└── src/\n    ├── annotations/             # Annotation definitions\n    │   ├── database_column.dart\n    │   ├── database_index.dart\n    │   ├── database_table.dart\n    │   ├── foreign_key.dart\n    │   └── rls_policy.dart\n    ├── generators/              # Code generation logic\n    │   └── schema_generator.dart\n    └── models/                  # Data models\n        ├── column_types.dart\n        ├── default_values.dart\n        ├── foreign_key_actions.dart\n        ├── index_types.dart\n        ├── migration_config.dart\n        ├── partition_strategy.dart\n        ├── table_constraints.dart\n        └── validators.dart\n```\n\n---\n\n## 🤝 Contributing\n\nWe welcome contributions! Here's how you can help:\n\n### 🐛 Bug Reports\n\n- Use the [issue tracker](https://github.com/ahmtydn/supabase_annotations/issues)\n- Include a minimal reproduction case\n- Provide environment details (Dart version, OS, etc.)\n\n### 💡 Feature Requests\n\n- Check existing [discussions](https://github.com/ahmtydn/supabase_annotations/discussions)\n- Explain the use case and benefits\n- Consider implementation complexity\n\n### 🔧 Pull Requests\n\n1. **Fork** the repository\n2. **Create** a feature branch (`git checkout -b feature/amazing-feature`)\n3. **Add** tests for new functionality\n4. **Ensure** all tests pass (`dart test`)\n5. **Run** analysis (`dart analyze`)\n6. **Commit** changes (`git commit -m 'Add amazing feature'`)\n7. **Push** to branch (`git push origin feature/amazing-feature`)\n8. **Submit** a pull request\n\n### 📋 Development Guidelines\n\n- Follow the existing code style\n- Add comprehensive tests\n- Update documentation\n- Include examples for new features\n- Ensure backward compatibility\n\n---\n\n## 📞 Support \u0026 Community\n\n### 📚 **Documentation**\n- [API Reference](https://pub.dev/documentation/supabase_annotations/latest/)\n- [Migration Guide](https://github.com/ahmtydn/supabase_annotations/blob/main/MIGRATION_GUIDE.md)\n- [Examples](https://github.com/ahmtydn/supabase_annotations/tree/main/example)\n\n### 💬 **Community**\n- [GitHub Discussions](https://github.com/ahmtydn/supabase_annotations/discussions)\n- [Issue Tracker](https://github.com/ahmtydn/supabase_annotations/issues)\n\n### 🆘 **Need Help?**\n- Check the [FAQ](https://github.com/ahmtydn/supabase_annotations/discussions/categories/q-a)\n- Search existing [issues](https://github.com/ahmtydn/supabase_annotations/issues)\n- Ask in [discussions](https://github.com/ahmtydn/supabase_annotations/discussions)\n\n---\n\n## 📄 License\n\nThis project is licensed under the **MIT License** - see the [LICENSE](LICENSE) file for details.\n\n---\n\n## 🙏 Acknowledgments\n\n- **Supabase Team** - For creating an amazing platform\n- **Dart Team** - For excellent tooling and language features\n- **PostgreSQL Community** - For the world's most advanced open source database\n- **Contributors** - For making this project better\n\n---\n\n## 🌟 Show Your Support\n\nIf this project helped you, please consider:\n\n- ⭐ **Star** the repository\n- 🔗 **Share** with your team\n- 🐛 **Report** issues\n- 💡 **Suggest** improvements\n- 🤝 **Contribute** code\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\n**Built with ❤️ for the Supabase and Dart communities**\n\n[🌐 Website](https://github.com/ahmtydn/supabase_annotations) • [📚 Docs](https://pub.dev/packages/supabase_annotations) • [💬 Community](https://github.com/ahmtydn/supabase_annotations/discussions)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmtydn%2Fsupabase_annotations","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahmtydn%2Fsupabase_annotations","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahmtydn%2Fsupabase_annotations/lists"}