logosophe Cursor Rules — Cursor Rules | Neura Market
    Neura MarketNeura Market/Cursor
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeek
    CoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsBlogVideosGuidesCoursesCommunityExtensionsTrendingGenerate
    CursorRuleslogosophe Cursor Rules
    Back to Rules
    Frontend

    logosophe Cursor Rules

    anchorwrite April 15, 2026
    0 copies 0 downloads

    - **Monorepo**: Uses Yarn workspaces with apps/* and packages/* structure

    Rule Content
    # Logosophe Project Rules and Context
    
    ## Project Structure
    - **Monorepo**: Uses Yarn workspaces with apps/* and packages/* structure
    - **Main App**: `apps/worker` - Next.js app using OpenNext for Cloudflare Workers
    - **Email Worker**: `apps/email-worker` - Separate Cloudflare Worker for email processing
    - **Packages**: `packages/common`, `packages/config`, `packages/database` for shared code
    
    ## Development Setup
    - **Package Manager**: Yarn (not npm) - use `yarn` commands
    - **Local Development**: `yarn dev` starts the development server
    - **Tunnel**: `yarn tunnel:logosophe-dev` starts Cloudflare tunnel for local-dev.logosophe.com
    - **Database**: Cloudflare D1 database with local and remote instances
    
    ## Database Configuration
    - **Database Name**: `logosophe`
    - **Database ID**: `fd7b2b89-eedd-4111-ba68-fdb05cdf2995`
    - **Binding**: `DB` in wrangler configuration
    - **Local Database**: Located at `.wrangler/state/v3/d1`
    - **Remote Database**: Cloudflare D1 instance
    
    ## Database Commands
    - **List databases**: `yarn wrangler d1 list`
    - **Execute on local**: `yarn wrangler d1 execute logosophe --command "SQL"`
    - **Execute on remote**: `yarn wrangler d1 execute logosophe --remote --command "SQL"`
    - **Create database**: `yarn wrangler d1 create logosophe`
    - **Delete database**: `yarn wrangler d1 delete logosophe`
    
    ## Database Schema Lookup
    - **Check table structure**: `yarn wrangler d1 execute logosophe --command "PRAGMA table_info(table_name);"`
    - **Session token lookup**: Join sessions and users tables to get email from session token:
      ```sql
      SELECT s.sessionToken FROM sessions s 
      JOIN users u ON s.userId = u.id 
      WHERE u.email = '[email protected]' 
      ORDER BY s.expires DESC LIMIT 1;
      ```
    - **Email from session token**: Reverse lookup to get email from session token:
      ```sql
      SELECT u.email FROM sessions s 
      JOIN users u ON s.userId = u.id 
      WHERE s.sessionToken = 'token_here';
      ```
    - **Session expiration check**: Include expires field when querying sessions:
      ```sql
      SELECT s.sessionToken, s.expires FROM sessions s 
      JOIN users u ON s.userId = u.id 
      WHERE u.email = '[email protected]' 
      ORDER BY s.expires DESC LIMIT 1;
      ```
    
    ## Wrangler Configuration
    - **Config file**: `apps/worker/wrangler.jsonc`
    - **Must run wrangler commands from**: `apps/worker/` directory
    - **Database binding**: Configured in `d1_databases` section
    - **Environment**: Uses production database by default, no local-dev environment configured
    
    ## UI Framework
    - **No Tailwind CSS**: Project uses Radix-UI/Themes instead
    - **Components**: Located in `packages/common/components/`
    - **UI Components**: Radix-UI components in `packages/common/components/ui/`
    
    ### Header Component Architecture
    - **Main Header**: Located at `apps/worker/app/components/Header/index.tsx` - used on root page (`/`)
    - **Harbor AppBar**: Located at `apps/worker/app/[lang]/harbor/appbar.tsx` - used in harbor routes
    - **Dashboard AppBar**: Located at `apps/worker/app/dashboard/appbar.tsx` - used in dashboard routes
    - **Subscriber Pages AppBar**: Located at `apps/worker/app/components/SubscriberPagesAppBar.tsx` - used in subscriber page routes
    
    ### Header Component Role-Based Navigation
    - **Credentials users (admin/tenant)**: See "Dashboard" → navigate to `/dashboard`
    - **Non-Credentials users who are subscribers**: See "Harbor" (in their language) → navigate to `/[lang]/harbor`
    - **Everyone else** (including OAuth users without subscriber role and unauthenticated users): See "Sign In" → navigate to `/signin`
    - **Role checking**: Uses `session.user.role` from RBAC system to determine display and navigation
    - **Internationalization**: Subscriber users see "Harbor" in their language, others see English fallback text
    
    ## Authentication
    - **Framework**: NextAuth v5 with D1Adapter
    - **Providers**: Google, Apple, Resend, Credentials
    - **Configuration**: `apps/worker/app/auth.ts`
    
    ### Auth.js v5 Database Access Patterns
    - **OpenNext Cloudflare**: Use `getCloudflareContext({async: true})` to access D1 database
    - **Database Binding**: Access via `context.env.DB` after getting context
    - **Async Pattern**: Always await the context: `const context = await getCloudflareContext({async: true})`
    - **Error Handling**: Wrap database access in try/catch blocks
    - **Fallback Strategy**: Continue with operation even if database logging fails
    
    ### Auth.js v5 Configuration Patterns
    - **Async NextAuth**: Configure NextAuth as async function to get database context
    - **Session Strategy**: Use `'database'` strategy for session management
    - **Custom Adapter**: Create custom adapter with role support for D1
    - **Event Logging**: Log authentication events in SystemLogs table
    - **Provider Configuration**: Configure each provider with proper callbacks
    
    ### Database Schema for Auth.js
    - **Users Table**: Standard Auth.js users table with id, name, email, emailVerified, image
    - **Accounts Table**: OAuth provider accounts with userId, provider, type, access_token, etc.
    - **Sessions Table**: Session management with sessionToken, userId, expires
    - **Verification Tokens**: For email verification flows
    - **Credentials Table**: Custom table for admin/tenant users with Email, Password, Role
    - **Subscribers Table**: Custom table for regular users with email, provider, etc.
    
    ### SystemLogs Integration
    - **Log Types**: Use 'AUTH' for authentication events
    - **Required Fields**: userId, userEmail, provider, activityType, ipAddress, userAgent
    - **Metadata**: Store additional context as JSON string
    - **Column Names**: Use 'LogType' and 'UserEmail' (not 'Type' and 'Email')
    - **Error Handling**: Log errors but don't fail authentication flow
    
    ### Sign-In/Sign-Out Patterns
    - **Server Actions**: Use inline server actions with 'use server' directive
    - **Redirect Handling**: Let Auth.js handle redirects with `redirectTo` parameter
    - **Error Handling**: Don't catch `NEXT_REDIRECT` errors from Auth.js
    - **Session Checking**: Use `await auth()` to check current session
    - **Role-Based Redirects**: Check user role before redirecting to appropriate page
    
    ### NEXT_REDIRECT Error Handling
    - **Root Cause**: `redirect()` throws `NEXT_REDIRECT` error for Next.js to handle
    - **Problem**: Try/catch blocks can intercept this error and prevent proper redirects
    - **Solution**: Move `redirect()` calls outside try/catch blocks
    - **Pattern**: Store error messages in variables, handle redirects separately
    - **Auth.js Redirects**: Let `signIn()` with `redirectTo` handle successful redirects naturally
    
    ### Database Query Best Practices
    - **Direct Queries**: Use `db.prepare().bind().first()` or `db.prepare().bind().all()`
    - **Type Safety**: Always type query results explicitly
    - **Error Handling**: Let SQL errors propagate naturally
    - **Transaction Avoidance**: Don't use transactions with D1 (not supported)
    - **Connection Management**: Get fresh context for each database operation
    
    ### Authentication Flow
    1. **Sign-In**: `signIn('credentials', { email, password, redirectTo })`
    2. **Session Check**: `const session = await auth()`
    3. **Role Resolution**: Query Credentials/Subscribers tables for user role
    4. **Redirect Logic**: Based on role (admin → dashboard, others → harbor)
    5. **Logging**: Log authentication events to SystemLogs
    6. **Sign-Out**: Use `handleSignOut()` action for proper logging
    
    ### Common Pitfalls
    - **Context Access**: Always use `await getCloudflareContext({async: true})`
    - **Column Names**: Use correct database column names (LogType, UserEmail)
    - **Error Catching**: Don't catch `NEXT_REDIRECT` errors from Auth.js
    - **Redirect Timing**: Handle redirects outside try/catch blocks
    - **Session Management**: Use database strategy for persistent sessions
    
    ## Migration Context
    - **Source Project**: anchorwrite (uses Cloudflare Pages + Next.js from Vercel)
    - **Target Project**: logosophe (uses OpenNext + Cloudflare Workers)
    - **Migration Strategy**: Stage-by-stage migration from anchorwrite to logosophe
    - **Current Status**: Database setup complete, ready for schema migration
    
    ## Key Files
    - **Main config**: `apps/worker/wrangler.jsonc`
    - **Auth config**: `apps/worker/app/auth.ts`
    - **Database utils**: `packages/common/utils/database.ts`
    - **Local dev setup**: `LOCAL_DEVELOPMENT.md`
    - **Project structure**: `Structure.md`
    
    ## Development Workflow
    1. Start tunnel: `yarn tunnel:logosophe-dev`
    2. Start dev server: `yarn dev`
    3. Access at: https://local-dev.logosophe.com
    4. Database operations: Run from `apps/worker/` directory
    
    ## Database Migration System
    - **Migration Location**: `packages/database/migrations/`
    - **Current Migration**: `001-initial-schema.sql` (applied to both local and remote)
    - **Migration Script**: `packages/database/migrations/apply-migration.sh`
    - **Documentation**: `packages/database/migrations/README.md`
    
    ### Migration Commands
    - **Apply to local**: `./apply-migration.sh 001-initial-schema.sql`
    - **Apply to remote**: `./apply-migration.sh 001-initial-schema.sql --remote`
    - **Manual local**: `yarn wrangler d1 execute logosophe --file=../../packages/database/migrations/001-initial-schema.sql`
    - **Manual remote**: `yarn wrangler d1 execute logosophe --remote --file=../../packages/database/migrations/001-initial-schema.sql`
    
    ### Database Schema Overview
    - **40+ Tables** organized by system (Authentication, Media, Messaging, Workflows, etc.)
    - **Foreign Key Constraints** for data integrity
    - **Performance Indexes** on frequently queried columns
    - **Initial Data** including roles, permissions, and access templates
    - **Soft Deletes** using IsDeleted flags where appropriate
    - **Audit Logging** via SystemLogs table
    
    ### Key Database Tables
    - **Authentication**: Credentials, Subscribers, accounts, sessions, users, verification_tokens
    - **Tenant Management**: Tenants, TenantUsers, UserRoles
    - **Media Management**: MediaFiles, MediaAccess, MediaAccessTemplates, MediaShareLinks
    - **Messaging**: Messages, MessageRecipients, MessageAttachments, MessageThreads, MessageRateLimits, UserBlocks
    - **Workflows**: Workflows, WorkflowHistory, WorkflowMessages, WorkflowParticipants
    - **System**: SystemLogs, SystemSettings, UserActivity, UserAvatars, TestSessions
    - **Resources**: Resources, ResourceAccess, TenantResources, PublishedContent, Preferences
    
    ### Migration Guidelines
    1. **Use IF NOT EXISTS** for CREATE TABLE statements
    2. **Use INSERT OR IGNORE** for INSERT statements
    3. **Include Indexes** for performance
    4. **Document Changes** in README.md
    5. **Test Locally First** before applying to remote 
    
    ## Email Worker Deployment
    - After making changes to the email worker:
      1. Navigate to the email worker directory: `cd apps/email-worker`
      2. Run `yarn deploy` which:
         - Builds the worker (`yarn build`)
         - Deploys to Cloudflare (`wrangler deploy`)
      3. This ensures the compiled JavaScript matches the TypeScript source
      4. Required for changes to take effect in production
    
    ## Logging & Analytics System
    - **Current Status**: Production-ready, enterprise-grade analytics platform
    - **Implementation**: Complete NormalizedLogging system with dual analytics dashboards
    - **Features**: Real-time analytics, trend analysis, multi-language support
    - **Documentation**: See `LOGGING_AND_ANALYTICS_README.md` for complete details
    
    
    
    ## User Authentication & Roles
    - There are two types of users:
      - Authenticated users who have signed in using an Auth JS v5 provider
      - Non-Authenticated users who have not signed in using an Auth JS v5 provider
    - There are three types of authenticated users:
      - Credentials provider users
      - Non-Credentials provider users who have not opted in as subscribers
      - Non-Credentials provider users who have opted in as subscribers
     - Credentials provider users are administrative and are stored in the Credentials table:
      - admin role: Full system access
      - tenant role: Full access to their assigned tenants
    - Non-Credentials provider users who have not opted in as subscribers have limited access and are stored in the TenantUsers and UserRoles tables:
      - TenantId: default
      - RoleId: user
    - Non-Credentials provider users who have opted in as subscribers are also stored in the Subscribers table
    - Subscribers have enhanced access and can be assigned roles and tenants:
      - Roles are in the Roles table
      - Tenants are in the Tenants table
      - Can have multiple different roles per tenant (e.g., author and editor in tenant-001, author in tenant-002)
      - Tenant membership is stored in the TenantUsers table
      - Role assignments are stored in the UserRoles table
    
    ## User Profile Data
    - **Only subscribers and admin users have profiles** - regular users (non-subscribers) do not have profile data
    - **Subscriber profiles** are stored in the Subscribers table with fields: Name, Email, Active, etc.
    - **Admin user profiles** are stored in the Credentials table with fields: Email, Role, etc.
    - **Profile API endpoints** should check the appropriate table based on user type:
      - Subscribers: Check Subscribers table first, fall back to users table
      - Admin users: Check Credentials table first, fall back to users table
      - Regular users: Only check users table (limited profile data)
    
    ## Role-Based Permissions
    - Static permissions per role:
      - author: write, view, upload, download, delete, link, share
      - agent: view, download, link
    - Access types: 'view', 'download', 'edit', 'delete', 'upload', 'share', 'unshare', 'link', 'unlink'
    
    ## Access Control Patterns
    - Use shared access control functions from @/lib/access:
      - isSystemAdmin: Check if user has global admin privileges (Credentials user with admin role)
      - isTenantAdminFor: Check if user has tenant admin privileges for a specific tenant
      - withTenantPermission: Check tenant-specific permissions
    - Admin access patterns:
      - Global admins (isSystemAdmin) have full access to all resources
      - Credentials users with 'tenant' role:
        - Have system admin-level control within their assigned tenants
        - Can perform all operations (create, read, update, delete) for their tenants
        - Cannot access resources from other tenants
        - Cannot perform system-wide operations
      - Regular users require explicit tenant membership and role assignments
    - Access control implementation:
      - Check authentication first (session?.user?.email)
      - Then check admin status using isSystemAdmin
      - For Credentials tenant users:
        - Check Credentials table for 'tenant' role
        - Use isTenantAdminFor to verify tenant membership and role
        - Grant full access within tenant scope
      - Finally check tenant-specific permissions if needed
    - Role resolution:
      - Auth flow directly checks Credentials and Subscribers tables
      - Credentials table takes precedence for admin/tenant roles
      - Subscribers table checked for subscriber role
      - Default to 'user' role if no other roles found
    - Avoid duplicating admin checks:
      - Use isSystemAdmin instead of direct Credentials table queries
      - Use isTenantAdminFor for tenant-specific admin checks
      - Keep admin check logic consistent across all routes
      - Maintain single source of truth for admin status
    
    ## Database Schema Verification
    - Always verify actual database schema using wrangler:
    - Don't rely solely on migration files:
      - Migration files may be out of sync with actual schema
      - Direct database queries show current state
      - Helps identify discrepancies between environments
    - Common tables to verify:
      - MediaFiles
      - MediaShareLinks
      - UserRoles
      - TenantUsers
      - MediaAccess
      - Credentials
      - Subscribers
      - users
    - When debugging issues:
      - Check schema first
      - Compare local vs production
      - Verify foreign key constraints
      - Check indexes and unique constraints
    
    ## Share Link Requirements
    - User must have:
      - A role with 'link' permission
      - Membership in at least one tenant that overlaps with the media file's tenants
    - Share links are viewable by any anonymous Internet user
    - No tenant context needed in the share URL
    - Access control happens at creation time
    - Share links are tenant-agnostic:
      - Once created, they can be accessed by anyone with the valid token
      - No tenant membership or authentication required to use the link
      - Access is controlled solely by the share token and its properties (expiration, max uses)
      - TenantId in MediaShareLinks is only used for creation permissions, not access control
    
    ## Logging Requirements
    
    ### 🎯 **IMPORTANT: Use NormalizedLogging for All User Actions**
    
    **The Logosophe system has been completely migrated to use `NormalizedLogging` for all user action logging. DO NOT use `SystemLogs` directly for user actions.**
    
    #### **Logging Architecture**
    - **User Action Logging**: Use `NormalizedLogging` class for all user interactions
    - **Database Management**: `SystemLogs` is retained ONLY for essential database operations
    - **Import Pattern**: `import { NormalizedLogging, extractRequestContext } from '@/lib/normalized-logging'`
    
    #### **NormalizedLogging Usage Pattern**
    ```typescript
    // 1. Import the required classes
    import { NormalizedLogging, extractRequestContext } from '@/lib/normalized-logging';
    
    // 2. Initialize in your route handler
    const normalizedLogging = new NormalizedLogging(db);
    
    // 3. Extract request context for IP and User-Agent
    const { ipAddress, userAgent } = extractRequestContext(request);
    
    // 4. Use appropriate logging method based on operation type
    await normalizedLogging.logMediaOperations({
      userEmail: access.email,
      tenantId: tenantId || 'system',
      activityType: 'upload_file',
      accessType: 'write',
      targetId: mediaId.toString(),
      targetName: fileName,
      ipAddress,
      userAgent,
      metadata: { fileSize, contentType, language: 'en' }
    });
    ```
    
    #### **Available Logging Methods**
    | Method | Purpose | LogType | Use Case |
    |--------|---------|---------|----------|
    | `logMediaOperations()` | Media file operations | `media_operations` | Upload, download, view, delete, share |
    | `logWorkflowOperations()` | Workflow management | `workflow_operations` | Create, update, delete, invite |
    | `logMessagingOperations()` | Messaging system | `messaging_operations` | Send, archive, read, delete |
    | `logUserManagement()` | User operations | `user_management` | Role assignment, profile updates |
    | `logAuthentication()` | Auth events | `authentication` | Sign in, sign out, password changes |
    | `logTestOperations()` | Test sessions | `test_operations` | Test creation, validation |
    | `logSystemOperations()` | System operations | `system_operations` | Settings, configuration, errors |
    
    #### **Required Parameters for All Logging Methods**
    ```typescript
    interface NormalizedLogData {
      userEmail: string;           // User's email address
      tenantId: string;            // Tenant context ('system' for admin operations)
      activityType: string;        // Specific action (e.g., 'upload_file', 'assign_role')
      accessType: NormalizedAccessType; // Operation type ('read', 'write', 'delete', 'admin', 'auth')
      targetId: string;            // ID of the target resource
      targetName: string;          // Human-readable description
      ipAddress?: string;          // From extractRequestContext(request)
      userAgent?: string;          // From extractRequestContext(request)
      metadata?: Record<string, any>; // Additional structured context
    }
    ```
    
    #### **Access Type Values**
    - **`read`**: View operations, access settings, content viewing
    - **`write`**: Create, update, modify operations
    - **`delete`**: Remove, delete, permanent deletion operations
    - **`admin`**: Administrative operations, system settings
    - **`auth`**: Authentication-related operations
    
    #### **Metadata Best Practices**
    ```typescript
    // Include relevant context for analytics
    metadata: {
      fileSize: file.FileSize,
      contentType: file.ContentType,
      language: 'en',              // User's preferred language
      userRole: 'author',          // User's role in this context
      tenantName: 'acme-corp',     // Tenant information
      action: 'upload_file',       // Operation description
      success: true,               // Operation result
      errorMessage: error?.message // If operation failed
    }
    ```
    
    #### **Request Context Extraction**
    ```typescript
    // Always use this for consistent IP and User-Agent extraction
    const { ipAddress, userAgent } = extractRequestContext(request);
    
    // This handles multiple IP headers automatically:
    // - x-forwarded-for (Cloudflare)
    // - cf-connecting-ip (Cloudflare)
    // - x-real-ip (Reverse proxy)
    ```
    
    #### **Tenant ID Guidelines**
    - **`'system'`**: For admin operations that affect the entire system
    - **`tenantId`**: For operations within a specific tenant
    - **`'default'`**: For operations in the default tenant (use sparingly)
    
    #### **Activity Type Naming Convention**
    - Use lowercase with underscores: `upload_file`, `assign_role`, `create_workflow`
    - Be descriptive: `update_protection_settings` not just `update_settings`
    - Include context: `tenant_add_user` not just `add_user`
    
    #### **Error Handling**
    ```typescript
    try {
      await normalizedLogging.logMediaOperations({...});
    } catch (error) {
      // Logging failure should not break the main operation
      console.error('Failed to log operation:', error);
      // Continue with the main operation
    }
    ```
    
    #### **When to Use SystemLogs (Database Management Only)**
    ```typescript
    // ONLY for these database operations:
    import { SystemLogs } from '@/lib/system-logs';
    
    const systemLogs = new SystemLogs(db);
    
    // Database retrieval
    await systemLogs.getArchivedLogs({...});
    await systemLogs.getLogStats();
    await systemLogs.queryLogs({...});
    
    // Database cleanup
    await systemLogs.archiveExpiredLogs(retentionDays);
    await systemLogs.hardDeleteArchivedLogs(hardDeleteDelay);
    ```
    
    #### **Migration Status**
    - ✅ **100% Complete**: All user action logging migrated to `NormalizedLogging`
    - ✅ **Build Success**: All TypeScript compilation errors resolved
    - ✅ **Analytics Ready**: Rich, consistent data structure for advanced analytics
    - ✅ **Type Safety**: Full TypeScript support with proper interfaces
    
    #### **Examples by Operation Type**
    
    ##### **Media Operations**
    ```typescript
    // File upload
    await normalizedLogging.logMediaOperations({
      userEmail: access.email,
      tenantId: tenantId,
      activityType: 'upload_file',
      accessType: 'write',
      targetId: mediaId.toString(),
      targetName: fileName,
      ipAddress,
      userAgent,
      metadata: { fileSize, contentType, language: 'en' }
    });
    
    // File download
    await normalizedLogging.logMediaOperations({
      userEmail: access.email,
      tenantId: tenantId,
      activityType: 'download_file',
      accessType: 'read',
      targetId: mediaId.toString(),
      targetName: fileName,
      ipAddress,
      userAgent,
      metadata: { downloadMethod: 'direct_link' }
    });
    ```
    
    ##### **User Management**
    ```typescript
    // Role assignment
    await normalizedLogging.logUserManagement({
      userEmail: adminEmail,
      tenantId: 'system',
      activityType: 'assign_role',
      accessType: 'admin',
      targetId: userEmail,
      targetName: `User ${userEmail}`,
      ipAddress,
      userAgent,
      metadata: { role: roleName, tenant: tenantId }
    });
    ```
    
    ##### **Workflow Operations**
    ```typescript
    // Workflow creation
    await normalizedLogging.logWorkflowOperations({
      userEmail: access.email,
      tenantId: tenantId,
      activityType: 'create_workflow',
      accessType: 'write',
      targetId: workflowId,
      targetName: workflowName,
      ipAddress,
      userAgent,
      metadata: { participants: participantCount, mediaFiles: mediaFileCount }
    });
    ```
    
    #### **Common Mistakes to Avoid**
    ❌ **Don't use SystemLogs for user actions**
    ```typescript
    // WRONG - Don't do this
    const systemLogs = new SystemLogs(db);
    await systemLogs.createLog({...});
    ```
    
    ✅ **Do use NormalizedLogging for user actions**
    ```typescript
    // CORRECT - Do this
    const normalizedLogging = new NormalizedLogging(db);
    await normalizedLogging.logMediaOperations({...});
    ```
    
    ❌ **Don't manually extract IP/User-Agent**
    ```typescript
    // WRONG - Don't do this
    ipAddress: request.headers.get('x-forwarded-for') || request.headers.get('x-real-ip'),
    userAgent: request.headers.get('user-agent')
    ```
    
    ✅ **Do use extractRequestContext**
    ```typescript
    // CORRECT - Do this
    const { ipAddress, userAgent } = extractRequestContext(request);
    ```
    
    #### **Testing Your Logging**
    1. **Check Build**: Ensure `yarn build` succeeds
    2. **Verify Logs**: Check that logs appear in the SystemLogs table
    3. **Test Analytics**: Verify logs appear in analytics dashboards
    4. **Check Types**: Ensure TypeScript compilation succeeds
    
    #### **Need Help?**
    - Check existing examples in the codebase
    - Refer to `apps/worker/app/lib/normalized-logging.ts` for method signatures
    - Use the logging utilities in `apps/worker/app/lib/logging-utils.ts`
    - Ensure all required parameters are provided
    
    ## Database Tables
    - MediaShareLinks:
      - Id, MediaId, ShareToken, CreatedBy, TenantId, CreatedAt, ExpiresAt, MaxAccesses, AccessCount
    - MediaAccess:
      - Id, MediaId, TenantId, RoleId, AccessType, GrantedAt, GrantedBy, ExpiresAt
    - TenantUsers:
      - TenantId, Email, RoleId, CreatedAt, UpdatedAt
    - SystemLogs:
      - Id, LogType, Timestamp, UserId, UserEmail, Provider, TenantId, ActivityType, AccessType, TargetId, TargetName, IpAddress, UserAgent, Metadata, IsDeleted
    
    ## SQL Query Preferences
    - Prefer direct SQL queries over intermediate variables
    - Avoid storing query results in variables unless necessary for reuse
    - Let SQL errors propagate naturally rather than checking success flags
    - Keep SQL queries inline for better readability and debugging
    - Use template literals for multi-line SQL queries
    - Maintain consistent SQL formatting with proper indentation
    - Use descriptive table aliases (e.g., 't' for Tenants, 'tu' for TenantUsers)
    - Include all relevant fields in SELECT statements rather than using *
    
    ## API Structure
    
    ### Media API Structure
    - All media-related endpoints should be under /api/media
    - Share link endpoints:
      - /api/media/[id]/link - Create share links
      - /api/media/share/[token] - Access shared media
      - /api/media/share/[token]/download - Download shared media
    - Cache control headers for share links:
      - Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate
      - Pragma: no-cache
      - Expires: 0
    
    ### Workflow API Structure
    The workflow system uses a three-tier API structure to separate concerns:
    
    #### Core Workflow APIs (`/api/workflow/`)
    **Purpose**: General workflow functionality for all authenticated users
    **Access**: All authenticated users with appropriate roles
    **Used by**: Harbor components, general workflow interfaces
    **Endpoints**:
    - `/api/workflow` (POST/GET) - Create workflows and list workflows for tenant
    - `/api/workflow/[id]` (GET/PUT/DELETE) - Get, update, delete individual workflows
    - `/api/workflow/[id]/stream` - SSE endpoint for real-time updates
    - `/api/workflow/history` - Get workflow history for user
    - `/api/workflow/history/detail/[id]` - Get detailed workflow history
    
    #### Harbor-Specific APIs (`/api/harbor/workflow/`)
    **Purpose**: Harbor interface-specific functionality
    **Access**: Harbor users with appropriate roles
    **Used by**: Harbor workflow components only
    **Endpoints**:
    - `/api/harbor/workflow/messages` (POST) - Send messages to workflows
    - `/api/harbor/workflow/stats` (GET) - Get workflow statistics for tenant
    
    #### Dashboard-Specific APIs (`/api/dashboard/workflow/`)
    **Purpose**: Admin-focused functionality for system management
    **Access**: System admins and tenant admins only
    **Used by**: Dashboard admin components only
    **Endpoints**:
    - `/api/dashboard/workflow/list` (GET) - List workflows with admin filtering
    - `/api/dashboard/workflow/[id]` (GET/PUT) - Admin workflow details and management
    - `/api/dashboard/workflow/stats` (GET) - System-wide workflow statistics
    - `/api/dashboard/workflow/analytics` (GET) - Workflow analytics
    - `/api/dashboard/workflow/reports` (GET) - Workflow reports
    - `/api/dashboard/workflow/history` (GET) - Admin workflow history
    - `/api/dashboard/workflow/bulk` (POST) - Bulk workflow operations
    - `/api/dashboard/workflow/health` (GET) - System health checks
    - `/api/dashboard/workflow/settings` (GET/PUT) - System settings
    
    ### Workflow API Usage Guidelines
    - **DO NOT create new workflow routes** - Use existing routes based on the interface context
    - **For Harbor components**: Use `/api/workflow/` (core) and `/api/harbor/workflow/` (harbor-specific)
    - **For Dashboard components**: Use `/api/dashboard/workflow/` (admin-specific)
    - **For general workflow functionality**: Use `/api/workflow/` (core APIs)
    - **When adding features**: Determine which interface needs the feature and use the appropriate API tier
    - **Avoid duplication**: Check existing APIs before creating new routes
    
    access_control:
      user_authentication:
        - All users must be authenticated with a valid email
        - Users except system admins must belong to at least one tenant
        - New users are initially assigned to the default tenant as part of the subscriber opt-in flow
        - Each tenant has its own set of roles and permissions
        - Roles are tenant-specific and cannot be shared across tenants
    
     
      access_control_patterns:
        - Media files are always associated with a tenant
        - Access is granted at the tenant level
        - Users can only access media files from tenants they belong to
        - Share links provide temporary or indefinite access to specific media files
        - Share links can be restricted by expiration date and access count
    
      database_schema:
        - MediaFiles table must have TenantId column
        - MediaAccess table must have MediaId, TenantId, and RoleId columns
        - MediaShareLinks table must have MediaId, ShareToken, and TenantId columns
    
      share_link_requirements:
        - Must have a unique ShareToken
        - Can be restricted by expiration date
        - Can be restricted by maximum number of accesses
        - Must be associated with a tenant
        - Must track access count
        - Must log all access attempts in SystemLogs
    
    # User Onboarding and Role Management
    tenant_users:
      table: TenantUsers
      primary_key: [TenantId, Email]
      roles:
        credentials_users:
          - admin: Global admin role
    
    ## TypeScript Database Query Patterns
    - Always type database query results explicitly:
      ```typescript
      const message = await db.prepare(`
        SELECT SenderEmail, CreatedAt, IsRecalled FROM Messages WHERE Id = ?
      `).bind(messageId).first() as { SenderEmail: string; CreatedAt: string; IsRecalled: boolean } | undefined;
      ```
    - For array results, use proper typing:
      ```typescript
      const tenants = await db.prepare(`
        SELECT Id FROM Tenants
      `).all() as { results: { Id: string }[] };
      ```
    - Import ResourceType from access module:
      ```typescript
      import { isSystemAdmin, isTenantAdminFor, hasPermission, type ResourceType } from './access';
      ```
    
    ## Messaging System Architecture
    - Database schema includes:
      - Messages: Core message storage with tenant awareness
      - MessageRecipients: Many-to-many relationship for message delivery
      - MessageAttachments: Media file attachments for messages
      - MessageThreads: Reply threading support
      - UserBlocks: User blocking functionality
      - MessageRateLimits: Rate limiting per user
      - SystemSettings: System-wide messaging controls
    - Access control integration:
      - Extends ResourceType to include 'message'
      - Extends Action type to include 'send'
      - Uses existing tenant-aware RBAC system
      - System admins have full messaging access
      - Tenant admins can send broadcast/announcement messages
      - Regular users need explicit 'message:send' permission
    
    ### API Route Organization
    - **Harbor Messaging** (`/api/harbor/messaging/*`): Subscriber-facing messaging functionality
      - Real-time messaging with SSE streaming
      - File attachments and link sharing
      - User message composition and management
    - **Dashboard Messaging** (`/api/dashboard/messaging/*`): Admin-facing messaging management
      - System-wide message management
      - User blocking and recipient management
      - System controls and statistics
    - **Clear Separation**: No route conflicts between harbor and dashboard APIs
    
    
    ## Messaging Features
    - Real-time messaging with FIFO queue for offline users
    - Rate limiting (configurable, default 1 message per minute)
    - User blocking system with tenant scope
    - Message states: read, deleted, forwarded, saved, replied
    - Media file attachments with access control
    - Message recall within configurable window
    - System-wide enable/disable toggle
    - Admin controls for message management
    - Tenant-aware recipient selection
    - Message threading and replies
    
    ## Rate Limiting Implementation
    - Uses MessageRateLimits table to track per-user limits
    - Configurable via SystemSettings table
    - Default: 60 seconds between messages
    - Tracks message count and reset time
    - Returns detailed rate limit information to clients
    
    ## User Blocking System
    - Tenant-scoped blocking (users can only block within their tenants)
    - Admin users can see all blocks in their tenants
    - Regular users can only see their own blocks
    - Blocks prevent message delivery but don't delete existing messages
    - Soft delete pattern (IsActive flag)
    
    ## System Controls
    - messaging_enabled: Global system toggle
    - messaging_rate_limit: Seconds between messages
    - messaging_max_recipients: Maximum recipients per message
    - messaging_recall_window: Seconds to recall messages
    - messaging_message_expiry: Days before message cleanup
    - All settings stored in SystemSettings table
    - Admin-only access to system controls
    
    ## API Endpoint Structure
    
    ### Harbor Messaging APIs (Subscribers)
    - `/api/harbor/messaging/send`: Send messages (POST)
    - `/api/harbor/messaging/stream/[tenantId]`: SSE streaming for real-time updates
    - `/api/harbor/messaging/unread-count`: Get unread message count (GET)
    - `/api/harbor/messaging/attachments/*`: File attachment management
    - `/api/harbor/messaging/links/*`: Link sharing functionality
    - `/api/harbor/messaging/messages/[id]`: Individual message operations (GET, PUT, DELETE)
    
    ### Dashboard Messaging APIs (Admins)
    - `/api/dashboard/messaging/send`: Send messages (POST)
    - `/api/dashboard/messaging/messages/[id]`: Message management (GET, PUT, DELETE)
    - `/api/dashboard/messaging/blocks/*`: User blocking management
    - `/api/dashboard/messaging/recipients`: Recipient listing (GET)
    - `/api/dashboard/messaging/system`: System controls (GET, PUT, POST for cleanup)
    - `/api/dashboard/messaging/route.ts`: Dashboard statistics (GET)
    
    ### API Design Principles
    - **Clear Separation**: Harbor and dashboard APIs are completely separate
    - **No Route Conflicts**: Each interface has its own namespace
    - **Consistent Patterns**: All endpoints require authentication and proper tenant access
    - **Error Handling**: Consistent error handling and logging patterns across all APIs
    
    ## Logging Integration
    - Uses existing SystemLogs table for messaging activities
    - Log types: MESSAGING for all messaging-related events
    - Logs include: send, read, block, unblock, system changes
    - Maintains audit trail for compliance and debugging
    - Includes metadata for additional context
    
    ## Development Patterns
    - Prefer minimal, targeted changes over sweeping modifications
    - Fix TypeScript errors incrementally
    - Use explicit type assertions for database results
    - Maintain consistency with existing access control patterns
    - Test API endpoints before building UI components
    - Follow existing error handling and logging patterns
          - tenant: Tenant admin role
        non_credentials_users:
          - user: Default role in default tenant
    
    user_roles:
      table: UserRoles
      primary_key: [TenantId, Email, RoleId]
      foreign_keys:
        tenant_users:
          columns: [TenantId, Email]
          references: TenantUsers
          on_delete: CASCADE
        roles:
          column: RoleId
          references: Roles
          on_delete: CASCADE
      usage:
        - Tracks additional roles
        - Used for subscribers who have opted in
        - Non-Credentials users get "subscriber" role after opt-in
        - Enables additional role assignments
    
    onboarding_flow:
      credentials_users:
        - Get admin/tenant role in TenantUsers
      non_credentials_users:
        - Start with "user" role in TenantUsers
        - Get "subscriber" role in UserRoles after opt-in
        - Can receive additional roles in UserRoles
    
    user_addition_process:
      steps:
        1: Add user to TenantUsers with 'user' role
        2: Add 'user' role to UserRoles for that user
        3: Add any additional roles to UserRoles
    
    benefits:
      - Clear separation between base roles and additional capabilities
      - Proper user onboarding and role progression
      - Flexible role assignment after initial onboarding
      - Ensures all users have at least the 'user' role in both tables
    
    # Role Checking Logic
    - Role types for non-sysadmin and non-tenant-admin users are dynamically validated against the Roles table
    - All roles from the database are included in the UserRole type
    - Runtime validation ensures type safety and database consistency
    - Access control checks all user roles:
      - Users get access if ANY of their roles are allowed
      - No artificial hierarchy between roles
      - Order of roles doesn't matter
      - Special cases for admin and tenant roles are maintained
      - Subscriber role is handled as a fallback
    - Role validation process:
      1. Check for admin role first
      2. Check for tenant role in Credentials
      3. Check all roles in UserRoles table
      4. Check Subscriber table as fallback
    - Access is granted if:
      - User has admin role
      - User has tenant role in Credentials and has a tenant in common with the resource tenant
      - User has ANY role that matches allowedRoles
    - Access is denied only if:
      - User has no roles
      - None of user's roles are in allowedRoles
      - User is not a subscriber (when subscriber role is required)
    
    ## Subscriber Management
    - Subscriber opt-in process:
      - Check for existing subscriber in Subscribers table
      - Create subscriber record in Subscribers table
      - Add subscriber role in UserRoles table
      - Keep subscriber record creation and role assignment separate
      - Handle opt-in at component level with sequential API calls
    - Role assignment:
      - Subscriber role should only be added during opt-in
      - Roles API handles role assignments
    
    ## Code Change Guidelines
    
    ### Error Handling
    - If a change introduces errors, stop and explain
    - Do not proceed with additional changes until current errors are resolved
    - If reverting changes, ensure all files are returned to original state
    - Document any errors encountered during changes
    
    ## Activity Logging Patterns
    - ActivityType should be descriptive but generic:
      - Use 'add_role' instead of 'add_role_editor'
      - Use 'tenant_add_user' for first-time tenant user addition
    - TargetId and TargetName should include specific details:
      - For role additions: 'email_role_name' (e.g., '[email protected]_editor')
      - For user additions: just the email
    - Always include:
      - TenantId for tenant-specific operations
      - IpAddress when available
      - UserAgent when available
    - Log both the initial user addition and subsequent role assignments separately
    - Use appropriate LogType (ACTIVITY, AUTH, MEDIA_ACCESS, MEDIA_SHARE)
    - Store additional context in Metadata field as JSON
    
    ## Role Management
    - First-time tenant user addition:
      - Must be logged as 'tenant_add_user' with LogType ACTIVITY
      - Requires entry in TenantUsers table
      - Initial role must be specified
    - Additional role assignments:
      - Must be logged as 'add_role' with LogType ACTIVITY
      - Requires entry in UserRoles table
      - Must check for existing role before adding
      - Must include both user and role in TargetId
    - Role verification:
      - Always verify role exists before assignment
      - Convert role names to lowercase with underscores for consistency
      - Handle unknown roles gracefully with fallback
    
    version: 1
    rules:
      - name: Translation Preferences
        description: Preferences for handling translations
        rules:
          - name: Use Familiar Form
            description: Use familiar form (du/tú/tu/jij) instead of formal form (Sie/usted/vous/u) in translations
            pattern: translation.json
            languages: [de, es, fr, nl]
          - name: Translation Structure
            description: Maintain consistent structure across all language files
            pattern: translation.json
    
      - name: Code Style Preferences
        description: Preferences for code style and formatting
        rules:
          - name: TypeScript Strict
            description: Use strict TypeScript settings
            pattern: tsconfig.json
          - name: React Component Structure
            description: Use functional components with TypeScript
            pattern: "*.tsx"
    
      - name: UI/UX Preferences
        description: Preferences for user interface and experience
        rules:
          - name: Text Alignment
            description: Prefer wider text containers to avoid unnecessary line breaks
            pattern: "*.tsx"
          - name: Form Validation
            description: Use comprehensive form validation with clear error messages
            pattern: "*.tsx"
          - name: Text and Button Spacing
            description: Ensure proper spacing between text and buttons to prevent elements running together
            pattern: "*.tsx"
    
    # Convert role names to lowercase with underscores for consistency
    # Handle unknown roles gracefully with fallback
    
    ## Radix UI Components
    - Container:
      - Default behavior forces min-height: 100vh
      - Use custom Container component instead
      - Custom Container properties:
        - width: 100%
        - maxWidth: 1200px
        - margin: 0 auto
        - padding: 0 var(--space-4)
      - Implementation: Simple Box component with above properties
      - Rule: Avoid using Radix UI Container directly
    
    ## Layout Structure
    - Page structure:
      - Header at top
      - Container with content
      - Footer right after content
    - Best practices:
      - Avoid forcing full viewport height
      - Let content determine natural height
      - Use Box component for padding and margins
      - Maintain consistent max-width across pages
    
    ## UI Component Spacing Guidelines
    
    ### Text and Button Spacing
    **Problem**: Text and Button elements running together without proper separation, appearing as a single element in the browser.
    
    **Solution**: Always use proper layout structure to separate descriptive text from action buttons.
    
    #### Dashboard Card Pattern (REQUIRED)
    ```tsx
    <Card style={{ flex: '1', minWidth: '300px' }}>
      <Box style={{ padding: '1.5rem' }}>
        <Heading size="4" style={{ marginBottom: '1rem' }}>
          Card Title
        </Heading>
        <Text color="gray" size="2" style={{ marginBottom: '1.5rem', display: 'block' }}>
          Description text that explains what this section does
        </Text>
        <Flex gap="2" wrap="wrap">
          <Button asChild>
            <Link href="/path">Primary Action</Link>
          </Button>
          <Button variant="soft" asChild>
            <Link href="/path">Secondary Action</Link>
          </Button>
        </Flex>
      </Box>
    </Card>
    ```
    
    #### Key Requirements
    1. **Text Display**: Always add `display: 'block'` to Text components that precede buttons
    2. **Button Containers**: Wrap buttons in `<Flex gap="2" wrap="wrap">` containers
    3. **Consistent Spacing**: Use `marginBottom: '1.5rem'` on text elements before buttons
    4. **Responsive Design**: Use `wrap="wrap"` for proper responsive behavior
    
    #### Anti-Pattern (AVOID)
    ```tsx
    // ❌ BAD: Text and button run together
    <Text color="gray" size="2" style={{ marginBottom: '1.5rem' }}>
      Description text here
    </Text>
    <Button asChild>
      <Link href="/path">Button Text</Link>
    </Button>
    ```
    
    #### Correct Pattern (USE)
    ```tsx
    // ✅ GOOD: Proper separation and layout
    <Text color="gray" size="2" style={{ marginBottom: '1.5rem', display: 'block' }}>
      Description text here
    </Text>
    <Flex gap="2" wrap="wrap">
      <Button asChild>
        <Link href="/path">Button Text</Link>
      </Button>
    </Flex>
    ```
    
    ### When to Apply These Rules
    - Dashboard card layouts with descriptive text and action buttons
    - Any interface where text content is immediately followed by interactive elements
    - Form layouts with explanatory text and submit buttons
    - Modal dialogs with description text and action buttons
    
    

    Tags

    nextjs

    Comments

    More Rules

    View all
    Web Development

    Next.js 15 + TypeScript Cursor Rules

    Comprehensive .cursorrules file for Next.js 15 App Router projects with TypeScript, enforcing server components by default, proper use of "use client" directive, and App Router conventions.

    C
    Community
    Backend Development

    Python FastAPI Best Practices Rules

    Cursor rules for Python FastAPI projects enforcing async patterns, Pydantic v2 models, dependency injection, and proper error handling.

    C
    Community
    Frontend Development

    React + TypeScript Component Rules

    Rules for consistent React component development with TypeScript interfaces, proper hook patterns, and component composition.

    C
    Community
    AI/ML

    Cursor Agent Mode Configuration

    Rules optimizing Cursor Agent mode behavior including multi-file editing context, session management, and autonomous task completion patterns.

    C
    Cursor Team
    Frontend Development

    Tailwind CSS + shadcn/ui Rules

    Cursor rules for projects using Tailwind CSS with shadcn/ui component library, enforcing consistent utility class usage and component patterns.

    C
    Community
    Backend Development

    Go Backend Service Rules

    Rules for Go backend services enforcing idiomatic Go patterns, proper error handling, and clean architecture conventions.

    C
    Community

    Stay up to date

    Get the latest Cursor prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for Cursor and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.