diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..a2a88bf --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,940 @@ +# Aquiis Property Management System - AI Agent Instructions + +## Development Workflow + +### Feature Branch Strategy + +**CRITICAL: Use the feature → development → main workflow. Main branch is protected and only accepts pull requests.** + +**Branch Hierarchy:** + +``` +main (protected, production-ready) + ↑ Pull Request (after CI passes) +development (integration testing) + ↑ Direct merge +feature/Phase-X-Feature-Name +``` + +**Workflow:** + +1. **Create Feature Branch from Development**: + + ```bash + # Ensure you're on development branch + git checkout development + git pull origin development + + # Create feature branch + git checkout -b feature/Phase-X-Feature-Name + ``` + + - Use descriptive names: `feature/Phase-6-Workflow-Services-and-Automation` + - Always branch from `development`, never from `main` + +2. **Development on Feature Branch**: + - All commits for the feature go to the feature branch + - Build and test frequently to ensure no breaking changes + - Keep commits focused and atomic + - Push feature branch to remote regularly for backup + +3. **Merge to Development** (after feature is complete and tested): + + ```bash + # Ensure build succeeds with 0 errors + dotnet build Aquiis.sln + + # Switch to development and merge + git checkout development + git pull origin development + git merge feature/Phase-X-Feature-Name + + # Test the merged code in development + dotnet build Aquiis.sln + dotnet test + ``` + +4. **Create Pull Request to Main**: + + ```bash + # Push development branch to remote + git push origin development + ``` + + - Create pull request on GitHub: `development` → `main` + - Wait for CI tests to pass + - Review and merge PR on GitHub.com + +5. **Pull Changes Locally**: + + ```bash + # Switch to main and pull merged changes + git checkout main + git pull origin main + + # Test locally to verify + dotnet build Aquiis.sln + dotnet test + ``` + +**Branch Protection Rules:** + +- **Main**: Protected, requires pull request, cannot push directly +- **Development**: Integration branch for testing features before PR +- **Feature branches**: Short-lived, deleted after merge to development + +--- + +## Project Overview + +Aquiis is a multi-tenant property management system built with **ASP.NET Core 9.0 + Blazor Server**. It manages properties, tenants, leases, invoices, payments, documents, inspections, and maintenance requests with role-based access control. + +## Architecture Fundamentals + +### Multi-Tenant Design + +- **Critical**: Every entity has an `OrganizationId` for tenant isolation +- **UserContextService** (`Services/UserContextService.cs`) provides cached access to current user's `OrganizationId` +- All service methods MUST filter by `OrganizationId` - this is handled automatically by `BaseService` +- Never hard-code organization filtering - always use `await _userContext.GetActiveOrganizationIdAsync()` + +### Service Layer Architecture + +Aquiis uses a **layered service architecture** with entity-specific services inheriting from a base service: + +**Service Hierarchy:** + +``` +BaseService (2-Aquiis.Application/Services/BaseService.cs) + ├─ LeaseService (Entity-specific CRUD + business logic) + ├─ PropertyService + ├─ TenantService + ├─ InvoiceService + ├─ MaintenanceService + └─ [Entity]Service + +Workflow Services (2-Aquiis.Application/Services/Workflows/) + ├─ LeaseWorkflowService (Complex lease lifecycle management) + ├─ ApplicationWorkflowService (Rental application processing) + └─ AccountWorkflowService (User account workflows) + +Legacy: + └─ PropertyManagementService (Being phased out - do not extend) +``` + +**BaseService Pattern:** + +All entity services inherit from `BaseService` which provides: + +- ✅ **Automatic organization isolation** - All queries filtered by `OrganizationId` +- ✅ **Audit field management** - `CreatedBy`, `CreatedOn`, `LastModifiedBy`, `LastModifiedOn` set automatically +- ✅ **Soft delete support** - Respects `ApplicationSettings.SoftDeleteEnabled` +- ✅ **Validation hooks** - Override `ValidateEntityAsync()` for custom rules +- ✅ **Lifecycle hooks** - `SetCreateDefaultsAsync()`, `AfterCreateAsync()` + +**Standard CRUD Methods (inherited from BaseService):** + +- `GetByIdAsync(Guid id)` - Retrieves entity with org isolation +- `GetAllAsync()` - Returns all entities for active organization +- `CreateAsync(TEntity entity)` - Creates with automatic tracking fields +- `UpdateAsync(TEntity entity)` - Updates with org verification +- `DeleteAsync(Guid id)` - Soft/hard deletes based on settings + +**Entity-Specific Service Pattern:** + +```csharp +public class LeaseService : BaseService +{ + public LeaseService( + ApplicationDbContext context, + ILogger logger, + IUserContextService userContext, + IOptions settings) + : base(context, logger, userContext, settings) + { + } + + // Override for custom validation + protected override async Task ValidateEntityAsync(Lease entity) + { + // Check for overlapping leases + // Validate date ranges + // Business rule validation + + await base.ValidateEntityAsync(entity); + } + + // Add entity-specific methods + public async Task> GetLeasesForPropertyAsync(Guid propertyId) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(l => l.PropertyId == propertyId && !l.IsDeleted) + .Include(l => l.Property) + .Include(l => l.Tenant) + .Where(l => l.Property.OrganizationId == orgId) + .ToListAsync(); + } +} +``` + +**Workflow Services Pattern:** + +For complex multi-step business processes, use workflow services: + +```csharp +public class LeaseWorkflowService : BaseWorkflowService, IWorkflowState +{ + // State machine for lease transitions + public bool IsValidTransition(LeaseStatus from, LeaseStatus to) + + // Workflow orchestration methods + public async Task ActivateLeaseAsync(Guid leaseId) + public async Task RenewLeaseAsync(Guid leaseId, RenewalData data) + public async Task TerminateLeaseAsync(Guid leaseId, string reason) +} +``` + +**When to Use Each:** + +- **Entity Service** - CRUD operations, simple queries, validation +- **Workflow Service** - Multi-step processes, state transitions, orchestration +- **PropertyManagementService** - Legacy code only (do not extend) + +**Blazor Component Injection:** + +```csharp +@inject LeaseService LeaseService +@inject PropertyService PropertyService +@inject TenantService TenantService + +// NOT: @inject PropertyManagementService (legacy) +``` + +**CRITICAL: Tracking Fields Must Be Set at Service Layer** + +All tracking fields and organization context MUST be set at the **service layer**, never in UI components: + +- **Tracking Fields**: `CreatedBy`, `CreatedOn`, `LastModifiedBy`, `LastModifiedOn`, `OrganizationId` +- **Source of Truth**: Services inject `UserContextService` to get current user and active organization +- **Security**: UI cannot manipulate tracking fields or bypass organization isolation +- **Maintainability**: All tracking logic centralized in services (change once, apply everywhere) +- **Simplicity**: UI components don't need to inject `UserContextService` or pass these values + +**Service Method Pattern (CORRECT):** + +```csharp +// Service injects UserContextService +private readonly UserContextService _userContext; + +// Create method - tracking fields set internally +public async Task CreatePropertyAsync(Property property) +{ + var userId = await _userContext.GetUserIdAsync(); + var activeOrgId = await _userContext.GetActiveOrganizationIdAsync(); + + // Service sets tracking fields - UI never touches these + property.CreatedBy = userId; + property.CreatedOn = DateTime.UtcNow; + property.OrganizationId = activeOrgId; + + _dbContext.Properties.Add(property); + await _dbContext.SaveChangesAsync(); + return property; +} + +// Update method - LastModified tracking + org security check +public async Task UpdatePropertyAsync(Property property) +{ + var userId = await _userContext.GetUserIdAsync(); + var activeOrgId = await _userContext.GetActiveOrganizationIdAsync(); + + // Verify property belongs to active organization (security) + var existing = await _dbContext.Properties + .FirstOrDefaultAsync(p => p.Id == property.Id && p.OrganizationId == activeOrgId); + + if (existing == null) return false; + + // Service sets tracking fields + property.LastModifiedBy = userId; + property.LastModifiedOn = DateTime.UtcNow; + property.OrganizationId = activeOrgId; // Prevent org hijacking + + _dbContext.Entry(existing).CurrentValues.SetValues(property); + await _dbContext.SaveChangesAsync(); + return true; +} + +// Query method - automatic active organization filtering +public async Task> GetPropertiesAsync() +{ + var activeOrgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbContext.Properties + .Where(p => p.OrganizationId == activeOrgId && !p.IsDeleted) + .ToListAsync(); +} +``` + +**UI Pattern (CORRECT):** + +```csharp +// UI only passes entity - NO userId, NO organizationId +private async Task CreateProperty() +{ + // Simple, clean, secure + var created = await PropertyService.CreatePropertyAsync(newProperty); + Navigation.NavigateTo("/propertymanagement/properties"); +} +``` + +**❌ ANTI-PATTERN (DO NOT DO THIS):** + +```csharp +// BAD: UI passes tracking values (insecure, boilerplate, wrong layer) +public async Task CreatePropertyAsync(Property property, string userId, string organizationId) +{ + property.CreatedBy = userId; + property.OrganizationId = organizationId; + // ... +} + +// BAD: UI must inject UserContextService (wrong responsibility) +@inject UserContextService UserContext + +private async Task CreateProperty() +{ + var userId = await UserContext.GetUserIdAsync(); + var orgId = await UserContext.GetActiveOrganizationIdAsync(); + await PropertyService.CreatePropertyAsync(newProperty, userId, orgId); // WRONG +} +``` + +**Key Principles:** + +1. Services own tracking field logic - UI never sets these values +2. All queries automatically filter by active organization (via UserContextService) +3. Update operations verify entity belongs to active org (security) +4. UI components stay simple - just pass entities, no context plumbing +5. Future refactoring happens in services only (change once, not in 40+ UI files) + +### Component Architecture + +Aquiis uses a **three-tier component hierarchy** to enable code reuse across SimpleStart and Professional products while maintaining different complexity levels: + +**Component Tiers:** + +``` +Entity Components (Tier 1) (3-Aquiis.UI.Shared/Components/Entities/) + ├─ Pure presentation components + ├─ Minimal business logic + ├─ Maximum reusability + └─ Examples: LeaseListView, PropertyCard, TenantSearchBox + +Feature Components (Tier 2) (3-Aquiis.UI.Shared/Features/) + ├─ Fully-featured implementations + ├─ Complete CRUD operations + ├─ Business logic included + ├─ Service injection + └─ Examples: LeaseManagement, PropertyManagement, TenantManagement + +Product Pages (Tier 3) (4-Aquiis.SimpleStart/Features/ or 5-Aquiis.Professional/Features/) + ├─ Composition layer + ├─ Product-specific UX + ├─ Routing decisions + └─ Examples: SimpleStart uses Feature components directly, Professional uses custom compositions +``` + +**When to Use Each Tier:** + +- **Entity Component**: Building block UI elements (lists, cards, search boxes) + - Example: `LeaseListView.razor` displays leases with filters and grouping + - Usage: `` +- **Feature Component**: Complete feature implementation ready to use + - Example: `LeaseManagement.razor` provides full lease CRUD with navigation + - Usage: SimpleStart: `` (5 lines), Professional: Custom composition +- **Product Page**: Top-level routing and product-specific UX + - Example: SimpleStart `/propertymanagement/leases` → Uses LeaseManagement directly + - Example: Professional `/leases` → Custom layout with LeaseListView + custom panels + +**File Naming & Organization:** + +``` +3-Aquiis.UI.Shared/ + ├── Components/ + │ ├── Common/ (Cross-cutting: EntityFilterBar, Modal, etc.) + │ └── Entities/ (Entity-specific: Leases/, Properties/, Tenants/) + └── Features/ + ├── PropertyManagement/ + ├── LeaseManagement/ + └── TenantManagement/ + +4-Aquiis.SimpleStart/Features/ + └── PropertyManagement/Index.razor (@page "/propertymanagement/leases") + +5-Aquiis.Professional/Features/ + └── Leases/Index.razor (@page "/leases") +``` + +**Shared UI Components:** + +The `Components/Common/` folder contains reusable components used across all entities: + +- **EntityFilterBar.razor**: Generic filter bar with optional search, status, priority, type filters + - Generic types: `TStatus`, `TPriority`, `TType` (unconstrained for flexibility) + - Optional elements: `ShowSearch`, `ShowStatusFilter`, `ShowGroupToggle`, etc. + - Custom filter slot: `` RenderFragment for entity-specific filters + - Pattern: `@if (ShowProperty && data.Any())` for conditional rendering + +- **LeaseMetricsCard.razor**: Dashboard metric display with icon, title, value, trend +- **Modal.razor**: Reusable modal dialog with customizable content and actions +- **ConfirmDialog.razor**: Confirmation prompts with Yes/No actions + +**Example: SimpleStart vs Professional Usage:** + +```csharp +// SimpleStart: Direct feature usage (simple, fast to implement) +@page "/propertymanagement/leases" + + +// Professional: Custom composition (flexible, branded UX) +@page "/leases" +
+ + +
+``` + +### Soft Delete Pattern + +- Entities inherit from `BaseModel` which provides audit fields (`CreatedOn`, `CreatedBy`, `LastModifiedOn`, `LastModifiedBy`, `IsDeleted`) +- **Never hard delete** - always set `IsDeleted = true` when deleting +- Controlled by `ApplicationSettings.SoftDeleteEnabled` configuration +- All queries must filter `.Where(x => !x.IsDeleted)` - this is non-negotiable + +### Authentication & Authorization + +- ASP.NET Core Identity with custom `ApplicationUser` (adds `OrganizationId`, `FirstName`, `LastName`) +- Three primary roles: `Administrator`, `PropertyManager`, `Tenant` (defined in `ApplicationConstants`) +- Use `@attribute [Authorize(Roles = "Administrator,PropertyManager")]` on Blazor pages +- User context pattern: Inject `UserContextService` instead of repeatedly querying `AuthenticationStateProvider` + +## Property & Tenant Lifecycle Workflows + +### Property Status Management + +Properties follow a status-driven lifecycle (string values from `ApplicationConstants.PropertyStatuses`): + +- **Available** - Ready to market and show to prospects +- **ApplicationPending** - One or more applications submitted and under review +- **LeasePending** - Application approved, lease offered, awaiting tenant signature +- **Occupied** - Active lease in place +- **UnderRenovation** - Not marketable, undergoing repairs/upgrades +- **OffMarket** - Temporarily unavailable + +**Important:** `Property.Status` is a `string` field (max 50 chars), NOT an enum. Always use `ApplicationConstants.PropertyStatuses.*` constants. + +**Status transitions are automatic** based on application/lease workflow events. + +### Prospect-to-Tenant Journey + +1. **Lead/Inquiry** → ProspectiveTenant created with Status: `Inquiry` +2. **Tour Scheduled** → Tour record created, Status: `TourScheduled` +3. **Tour Completed** → Status: `Toured`, interest level captured +4. **Application Submitted** → RentalApplication created, **Property.Status → ApplicationPending**, Status: `ApplicationSubmitted` + - **Page:** `/propertymanagement/prospects/{id}/submit-application` + - Application fee collected (per-application, non-refundable) + - Application valid for 30 days, auto-expires if not processed + - Property status automatically changes from Available to ApplicationPending + - All required fields: current address, landlord info, employment, references + - Income-to-rent ratio calculated and displayed +5. **Screening** → ApplicationScreening created (background + credit checks), Status: `UnderReview` + - **Page:** `/propertymanagement/applications/{id}/review` (Initiate Screening button) + - Background check requested with status tracking + - Credit check requested with credit score capture + - Overall screening result: Pending, Passed, Failed, ConditionalPass +6. **Application Approved** → Lease created with Status: `Offered`, **Property.Status → LeasePending**, Status: `ApplicationApproved` + - **Page:** `/propertymanagement/applications/{id}/review` (Approve button after screening passes) + - All other pending applications for this property auto-denied + - Lease offer expires in 30 days if not signed + - `Lease.OfferedOn` and `Lease.ExpiresOn` (30 days) are set +7. **Lease Signed** → **Tenant created from ProspectiveTenant**, SecurityDeposit collected, **Property.Status → Occupied**, Status: `ConvertedToTenant` + - **Page:** `/propertymanagement/leases/{id}/accept` + - `TenantConversionService` handles conversion with validation + - `Tenant.ProspectiveTenantId` links back to prospect for audit trail + - `Lease.SignedOn` timestamp recorded for compliance + - SecurityDeposit must be paid in full upfront + - Move-in inspection auto-scheduled +8. **Lease Declined** → **Property.Status → Available or ApplicationPending** (if other apps exist), Status: `LeaseDeclined` + - `Lease.DeclinedOn` timestamp recorded +9. **Application Denied** → Status: `ApplicationDenied`, Property returns to Available if no other pending apps + +**Key Services:** + +- `TenantConversionService` - Handles ProspectiveTenant → Tenant conversion + - `ConvertProspectToTenantAsync(prospectId, userId)` - Creates tenant with audit trail + - Returns existing Tenant if already converted (idempotent operation) + - `IsProspectAlreadyConvertedAsync()` - Prevents duplicate conversions + - `GetProspectHistoryForTenantAsync()` - Retrieves full prospect history for compliance + +**Key Pages:** + +- `GenerateLeaseOffer.razor` - `/propertymanagement/applications/{id}/generate-lease-offer` + - Generates lease offer from approved application + - Sets `Lease.OfferedOn` and `Lease.ExpiresOn` (30 days) + - Updates Property.Status to LeasePending + - Auto-denies all competing applications for the property + - Accessible to PropertyManager and Administrator roles only + +- `AcceptLease.razor` - `/propertymanagement/leases/{id}/accept` + - Accepts lease offer with full signature audit trail + - Captures: timestamp, IP address, user ID, payment method + - Calls TenantConversionService to create Tenant record + - Sets `Lease.SignedOn`, updates status to Active + - Updates Property.Status to Occupied + - Prevents acceptance of expired offers (checks `Lease.ExpiresOn`) + - Includes decline workflow (sets `Lease.DeclinedOn`) + +**Lease Lifecycle Fields:** + +- `OfferedOn` (DateTime?) - When lease offer was generated +- `SignedOn` (DateTime?) - When tenant accepted/signed the lease +- `DeclinedOn` (DateTime?) - When tenant declined the offer +- `ExpiresOn` (DateTime?) - Offer expiration date (30 days from OfferedOn) + +**Status Constants:** + +- ProspectiveStatuses: `LeaseOffered`, `LeaseDeclined`, `ConvertedToTenant` +- ApplicationStatuses: `LeaseOffered`, `LeaseAccepted`, `LeaseDeclined` +- LeaseStatuses: `Offered`, `Active`, `Declined`, `Terminated`, `Expired` + +### Multi-Lease Support + +- Tenants can have **multiple active leases simultaneously** +- Same tenant can lease multiple units in same or different buildings +- Each lease has independent security deposit, dividend tracking, and payment schedule + +### Security Deposit Investment Model + +**Investment Pool Approach:** + +- All security deposits pooled into investment account +- Annual earnings distributed as dividends +- Organization takes configurable percentage (default 20%), remainder distributed to tenants +- Dividend = (TenantShare / ActiveLeaseCount) per lease +- **Losses absorbed by organization** - no negative dividends + +**Dividend Distribution Rules:** + +- **Pro-rated** for tenants who moved in mid-year (e.g., 6 months = 50% dividend) +- Distributed at year-end even if tenant has moved out (sent to forwarding address) +- Tenant chooses: apply as lease credit OR receive as check +- Each active lease gets separate dividend (tenant with 2 leases gets 2 dividends) + +**Tracking:** + +- `SecurityDepositInvestmentPool` - annual pool performance +- `SecurityDepositDividend` - per-lease dividend with payment method choice +- Full audit trail of investment performance visible in tenant portal + +### E-Signature & Audit Trail + +- Lease offers require acceptance (checkbox "I Accept" for dev/demo) +- Full signature audit: IP address, timestamp, document version, user agent +- Lease offer expires after 30 days if not signed +- Unsigned leases roll to month-to-month at higher rate + +## Code Patterns & Conventions + +### Enums & Constants Location + +- **Status and type values** stored as string constants in `ApplicationConstants.cs` static classes +- Example: `ApplicationConstants.PropertyStatuses.Available`, `ApplicationConstants.LeaseStatuses.Active` +- **Enums** (PropertyStatus, ProspectStatus, etc.) defined in `ApplicationSettings.cs` for type safety but NOT used in database +- Database fields use `string` type with validation against ApplicationConstants values +- Never hard-code status/type values - always reference ApplicationConstants classes + +### Blazor Component Structure + +```csharp +@page "/propertymanagement/entities/create" +@using Aquiis.SimpleStart.Components.PropertyManagement.Entities +@attribute [Authorize(Roles = "Administrator,PropertyManager")] +@inject PropertyService PropertyService +@inject UserContextService UserContext +@inject NavigationManager Navigation +@rendermode InteractiveServer + +// Component code follows... +``` + +### Creating Entities + +```csharp +// UI component creates entity with business data only +private async Task CreateEntity() +{ + // Service handles CreatedBy, CreatedOn, OrganizationId automatically + var created = await PropertyService.AddEntityAsync(entity); + Navigation.NavigateTo("/propertymanagement/entities"); +} +``` + +**Note:** Do NOT set tracking fields in UI. The service layer automatically sets: + +- `CreatedBy` - from `UserContextService.GetUserIdAsync()` +- `CreatedOn` - `DateTime.UtcNow` +- `OrganizationId` - from `UserContextService.GetActiveOrganizationIdAsync()` + +### Service Method Pattern + +```csharp +// Service method automatically handles organization context and tracking +public async Task> GetEntitiesAsync() +{ + // Get active organization from UserContextService (injected in constructor) + var activeOrgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbContext.Entities + .Include(e => e.RelatedEntity) + .Where(e => !e.IsDeleted && e.OrganizationId == activeOrgId) + .ToListAsync(); +} + +// Create method sets tracking fields internally +public async Task AddEntityAsync(Entity entity) +{ + var userId = await _userContext.GetUserIdAsync(); + var activeOrgId = await _userContext.GetActiveOrganizationIdAsync(); + + // Service owns this logic - UI never sets these + entity.CreatedBy = userId; + entity.CreatedOn = DateTime.UtcNow; + entity.OrganizationId = activeOrgId; + + _dbContext.Entities.Add(entity); + await _dbContext.SaveChangesAsync(); + return entity; +} +``` + +**Important:** Never expose `organizationId` or `userId` as parameters in service methods. Services get these values from `UserContextService` automatically. + +### Constants Usage + +- All dropdown values come from `ApplicationConstants` (never hard-code) +- Examples: `ApplicationConstants.LeaseStatuses.Active`, `ApplicationConstants.PropertyTypes.Apartment` +- Status/type classes are nested: `ApplicationConstants.PaymentMethods.AllPaymentMethods` + +### Entity Relationships + +- Properties have many Leases, Documents, Inspections +- Leases belong to Property and Tenant +- Invoices belong to Lease (get Property/Tenant through navigation) +- Always use `.Include()` to eager-load related entities in services + +## Development Workflows + +### Database Changes + +1. **EF Core Migrations**: Primary approach for schema changes + - Migrations stored in `Data/Migrations/` + - Run `dotnet ef migrations add MigrationName --project Aquiis.SimpleStart` + - Apply with `dotnet ef database update --project Aquiis.SimpleStart` + - Generate SQL script: `dotnet ef migrations script --output schema.sql` +2. **SQL Scripts**: Reference scripts in `Data/Scripts/` (not executed, for documentation) +3. Update `ApplicationDbContext.cs` with DbSet and entity configuration +4. Connection string in `appsettings.json`: `"DefaultConnection": "DataSource=Infrastructure/Data/app.db;Cache=Shared"` +5. **Database**: SQLite (not SQL Server) - scripts will be SQLite syntax + +### Development Workflows + +**Running the Application:** + +- **Ctrl+Shift+B** to run `dotnet watch` (hot reload, default build task) +- **F5** in VS Code to debug (configured in `.vscode/launch.json`) +- Or: `dotnet run` in `Aquiis.SimpleStart/` directory +- Default URLs: Check terminal output for ports +- Default admin: `superadmin@example.local` / `SuperAdmin@123!` + +### Build Tasks (VS Code) + +- `build` - Debug build (Ctrl+Shift+B) +- `watch` - Hot reload development mode +- `build-release` - Production build +- `publish` - Create deployment package + +### Background Services + +- **ScheduledTaskService** runs daily/hourly automated tasks + - Daily tasks: Late fee application, inspection scheduling, lease expiration notifications + - Hourly tasks: Data cleanup, cache refresh +- Registered as hosted service in `Program.cs` +- Add new scheduled tasks to `ScheduledTaskService.cs` with proper scoping +- Pattern: Create scoped service instances to access DbContext (avoid singleton issues) + +## PDF Generation + +- Uses **QuestPDF 2025.7.4** with Community License (configured in Program.cs) +- PDF generators in `Components/PropertyManagement/Documents/` (e.g., `LeasePdfGenerator.cs`) +- Always save generated PDFs to `Documents` table with proper associations +- Pattern: Generate → Save to DB → Return Document object → Navigate to view + +## File Naming & Organization + +### Component Structure + +``` +Components/PropertyManagement/[Entity]/ + ├── [Entity].cs (Model - inherits BaseModel) + ├── Pages/ + │ ├── [Entities].razor (List view) + │ ├── Create[Entity].razor + │ ├── View[Entity].razor + │ └── Edit[Entity].razor + └── [Entity]PdfGenerator.cs (if applicable) +``` + +### Route Patterns + +- List: `/propertymanagement/entities` +- Create: `/propertymanagement/entities/create` +- View: `/propertymanagement/entities/view/{id:int}` +- Edit: `/propertymanagement/entities/edit/{id:int}` + +## Common Pitfalls to Avoid + +1. **DO NOT** access `ApplicationDbContext` directly in components - always use entity-specific services +2. **DO NOT** extend or add methods to `PropertyManagementService` - it's legacy code being phased out +3. **DO NOT** forget `OrganizationId` filtering - security breach waiting to happen +4. **DO NOT** hard-code status values - use `ApplicationConstants` classes +5. **DO NOT** hard delete entities - always soft delete (check `SoftDeleteEnabled` setting) +6. **DO NOT** set tracking fields (`CreatedBy`, `CreatedOn`, `LastModifiedBy`, `LastModifiedOn`) in UI - services handle this automatically +7. **DO NOT** query without `.Include()` for navigation properties you'll need +8. **DO NOT** use `!` null-forgiving operator without null checks - validate properly +9. **DO NOT** create services without inheriting from `BaseService` - you'll lose org isolation and audit tracking +10. **DO NOT** forget to register new services in `DependencyInjection.cs` + +## Toast Notifications + +- Use `ToastService` (singleton) for user feedback instead of JavaScript alerts +- Pattern: `await JSRuntime.InvokeVoidAsync("toastService.showSuccess", "Message")` +- Types: Success, Error, Warning, Info +- Auto-dismiss after 5 seconds (configurable) + +## Document Management + +- Binary storage in `Documents.FileData` (VARBINARY(MAX)) +- View in browser: Use Blob URLs via `wwwroot/js/fileDownload.js` +- Download: Base64 encode and trigger download +- 10MB upload limit configured in components + +## Financial Features + +- Late fees auto-applied by `ScheduledTaskService` (daily at 2 AM) +- Payment tracking updates invoice status automatically +- Financial reports use `FinancialReportService` with PDF export +- Decimal precision: 18,2 for all monetary values + +## Inspection Tracking + +- 26-item checklist organized in 5 categories (Exterior, Interior, Kitchen, Bathroom, Systems) +- Routine inspections update `Property.NextRoutineInspectionDueDate` +- Generate PDFs with `InspectionPdfGenerator` and save to Documents + +## Key Files to Reference + +- `Program.cs` - Service registration, Identity config, startup logic +- `ApplicationConstants.cs` - All dropdown values, roles, statuses +- `BaseService.cs` - Abstract base service with org isolation and audit tracking +- `[Entity]Service.cs` - Entity-specific service patterns (LeaseService, PropertyService, etc.) +- `[Entity]WorkflowService.cs` - Workflow orchestration patterns for complex state machines +- `UserContextService.cs` - Multi-tenant context access +- `BaseModel.cs` - Audit field structure +- `ApplicationDbContext.cs` - Entity relationships +- `EntityFilterBar.razor` - Generic reusable filter component pattern +- `DependencyInjection.cs` - Service registration in Application layer + +## When Adding New Features + +1. **Create entity model** inheriting `BaseModel` with `OrganizationId` property +2. **Add DbSet** to `ApplicationDbContext` with proper relationships and configuration +3. **Create EF Core migration**: `dotnet ef migrations add [Name] --project Aquiis.SimpleStart` +4. **Create entity-specific service** inheriting `BaseService`: + - Add constructor with dependencies (DbContext, Logger, UserContext, Settings) + - Override `ValidateEntityAsync()` for business rules + - Add entity-specific query methods with org filtering + - Register service in DI container (`2-Aquiis.Application/DependencyInjection.cs`) +5. **Create workflow service** (if complex state transitions needed): + - Inherit from `BaseWorkflowService` + - Implement `IWorkflowState` if status machine required + - Add orchestration methods for multi-step processes + - Register in DI container +6. **Create Blazor components** following three-tier architecture: + - Entity component (if reusable primitive needed) + - Feature component (complete CRUD implementation) + - Product pages (composition and routing) +7. **Add constants** to `ApplicationConstants` for status/type values +8. **Update navigation** in `NavMenu.razor` if top-level feature +9. **Add scheduled tasks** to `ScheduledTaskService` if automation needed + +**Example Entity Service Creation:** + +```csharp +// 2-Aquiis.Application/Services/[Entity]Service.cs +public class DocumentService : BaseService +{ + public DocumentService( + ApplicationDbContext context, + ILogger logger, + IUserContextService userContext, + IOptions settings) + : base(context, logger, userContext, settings) + { + } + + protected override async Task ValidateEntityAsync(Document entity) + { + if (entity.FileData == null || entity.FileData.Length == 0) + throw new ValidationException("Document must have file data"); + + if (entity.FileData.Length > 10 * 1024 * 1024) // 10MB limit + throw new ValidationException("File size cannot exceed 10MB"); + + await base.ValidateEntityAsync(entity); + } + + public async Task> GetDocumentsForPropertyAsync(Guid propertyId) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(d => d.PropertyId == propertyId && !d.IsDeleted) + .Include(d => d.Property) + .Where(d => d.Property.OrganizationId == orgId) + .ToListAsync(); + } +} + +// Register in DependencyInjection.cs +services.AddScoped(); +``` + +## Code Style Notes + +- Use async/await consistently (no `.Result` or `.Wait()`) +- Prefer explicit typing over `var` for service/entity types +- Use string interpolation for logging: `$"Processing {entityId}"` +- Handle errors with try-catch and user-friendly messages +- Include XML comments on service methods describing purpose + +## Documentation & Roadmap Management + +### Documentation Structure + +The project maintains comprehensive documentation organized by implementation status and version: + +**Roadmap Folder** (`/Documentation/Roadmap/`): + +- **Purpose:** Implementation planning and feature proposals +- **Status:** Active consideration - may be approved or rejected +- **Workflow:** One file at a time - focus on current implementation +- **File Naming:** Descriptive names (e.g., `00-PROPERTY-TENANT-LIFECYCLE-ROADMAP.md`) +- **Rejection:** Rejected proposals have rejection reason added at the top of the file + +**Version Folders** (`/Documentation/vX.X.X/`): + +- **Purpose:** Completed implementation notes for each version release +- **Status:** Historical record of what was actually implemented +- **Content:** Feature additions, changes, and implementation details for that specific release +- **File Naming:** Match feature/module names (e.g., `multi-organization-management.md`) + +### Semantic Versioning & Database Management + +The project follows **Semantic Versioning (MAJOR.MINOR.PATCH)**: + +- **MAJOR** version (X.0.0): Breaking changes that trigger database schema updates +- **MINOR** version (0.X.0): Significant UI changes or new features (backward compatible) +- **PATCH** version (0.0.X): Bug fixes, minor updates, safe application updates + +**Current Development Status:** + +- **Production version:** v0.1.1 (in production) +- **Development version:** v0.2.0 (current work in progress) +- **Next major milestone:** v1.0.0 (when entity refactoring stabilizes) + +**Database Version Management:** + +The database filename and schema version are tracked separately from the application patch version: + +**Configuration in `appsettings.json`:** + +```json +{ + "ConnectionStrings": { + "DefaultConnection": "DataSource=Infrastructure/Data/app_v0.0.0.db;Cache=Shared" + }, + "DatabaseSettings": { + "DatabaseFileName": "app_v0.0.0.db", + "PreviousDatabaseFileName": "", + "SchemaVersion": "0.0.0" + } +} +``` + +**Versioning Rules:** + +1. **Database filename** follows pattern: `app_v{MAJOR}.{MINOR}.0.db` + - Tracks MAJOR and MINOR app versions only (ignores PATCH) + - Example: App v2.1.25 uses database `app_v2.1.0.db` + - Current: App v0.2.0 uses database `app_v0.0.0.db` (pre-v1.0.0) + +2. **Schema version** (`SchemaVersion` in settings): + - Matches database filename version + - Example: `app_v2.1.0.db` has `SchemaVersion: "2.1.0"` + - Current: `SchemaVersion: "0.0.0"` (active refactoring phase) + +3. **Version 1.0.0 milestone**: + - At v1.0.0, database management becomes more formal + - Database filename becomes: `app_v1.0.0.db` (from `app_v0.0.0.db`) + - `SchemaVersion` initializes to `"1.0.0"` + - Indicates entity models have stabilized + +4. **Migration triggers**: + - MAJOR version bump → Database schema migration required + - MINOR version bump → Database filename updates (new .db file) + - PATCH version bump → No database changes (application updates only) + +**Example Version Progression:** + +| App Version | Database File | Schema Version | Notes | +| ----------- | ------------- | -------------- | ----------------------------------- | +| v0.1.1 | app_v0.0.0.db | 0.0.0 | Production (active refactoring) | +| v0.2.0 | app_v0.0.0.db | 0.0.0 | Development (same schema) | +| v1.0.0 | app_v1.0.0.db | 1.0.0 | Milestone (entities stabilized) | +| v1.0.5 | app_v1.0.0.db | 1.0.0 | Patches (no DB change) | +| v1.1.0 | app_v1.1.0.db | 1.1.0 | Minor (new DB file) | +| v1.1.8 | app_v1.1.0.db | 1.1.0 | Patches (same DB) | +| v2.0.0 | app_v2.0.0.db | 2.0.0 | Major (breaking changes, migration) | + +**Implementation Workflow:** + +1. When incrementing MAJOR or MINOR version: + - Update `DatabaseFileName` in `appsettings.json` to new version + - Update `SchemaVersion` to match + - Set `PreviousDatabaseFileName` to old database name (for migration reference) + - Create EF Core migration if schema changes required + +2. When incrementing PATCH version: + - No changes to database settings + - Application version increments only + +3. Document completed features in `/Documentation/v{MAJOR}.{MINOR}.{PATCH}/` + +**Pre-v1.0.0 Strategy:** + +- Database remains at `app_v0.0.0.db` until v1.0.0 +- Allows rapid iteration and entity refactoring +- Schema migrations managed via EF Core Migrations folder +- At v1.0.0 release, formalize database versioning with `app_v1.0.0.db` diff --git a/0-Aquiis.Core/Constants/ApplicationConstants.cs b/0-Aquiis.Core/Constants/ApplicationConstants.cs index e6f7437..3d8e5a6 100644 --- a/0-Aquiis.Core/Constants/ApplicationConstants.cs +++ b/0-Aquiis.Core/Constants/ApplicationConstants.cs @@ -50,7 +50,7 @@ public static class OrganizationRoles /// /// PropertyManager - Full property management features (no admin/settings access) /// - public const string PropertyManager = "Property Manager"; + public const string PropertyManager = "PropertyManager"; /// /// Maintenance - Maintenance requests, work orders, and vendors @@ -176,6 +176,7 @@ public static class InvoiceStatuses public const string Paid = "Paid"; public const string Overdue = "Overdue"; public const string Cancelled = "Cancelled"; + public const string Voided = "Voided"; public static IReadOnlyList AllInvoiceStatuses { get; } = new List { @@ -183,7 +184,8 @@ public static class InvoiceStatuses PaidPartial, Paid, Overdue, - Cancelled + Cancelled, + Voided }; } @@ -193,13 +195,15 @@ public static class PaymentStatuses public const string Pending = "Pending"; public const string Failed = "Failed"; public const string Refunded = "Refunded"; + public const string Voided = "Voided"; public static IReadOnlyList AllPaymentStatuses { get; } = new List { Completed, Pending, Failed, - Refunded + Refunded, + Voided }; } public static class InspectionTypes @@ -275,6 +279,13 @@ public static class LeaseStatuses { Terminated, Expired }; + + public static IReadOnlyList DefaultStatuses { get; } = new List + { + Active, + MonthToMonth, + Terminated + }; } @@ -359,6 +370,44 @@ public static class MaintenanceRequestTypes }; } + /// + /// Repair type categories for logging work performed on properties. + /// Used by the Repair entity (work WITHOUT workflow). + /// + public static class RepairTypes + { + public const string Plumbing = "Plumbing"; + public const string Electrical = "Electrical"; + public const string HeatingCooling = "Heating/Cooling"; + public const string Appliance = "Appliance"; + public const string Structural = "Structural"; + public const string Landscaping = "Landscaping"; + public const string PestControl = "Pest Control"; + public const string Painting = "Painting"; + public const string Carpentry = "Carpentry"; + public const string Flooring = "Flooring"; + public const string Roofing = "Roofing"; + public const string Windows = "Windows/Doors"; + public const string Other = "Other"; + + public static IReadOnlyList AllRepairTypes { get; } = new List + { + Plumbing, + Electrical, + HeatingCooling, + Appliance, + Structural, + Landscaping, + PestControl, + Painting, + Carpentry, + Flooring, + Roofing, + Windows, + Other + }; + } + public static class MaintenanceRequestPriorities { public const string Low = "Low"; diff --git a/0-Aquiis.Core/Constants/ApplicationSettings.cs b/0-Aquiis.Core/Constants/ApplicationSettings.cs index e15454b..80fc7e8 100644 --- a/0-Aquiis.Core/Constants/ApplicationSettings.cs +++ b/0-Aquiis.Core/Constants/ApplicationSettings.cs @@ -9,6 +9,7 @@ public class ApplicationSettings public string Repository { get; set; } = string.Empty; public bool SoftDeleteEnabled { get; set; } public string SchemaVersion { get; set; } = "1.0.0"; + public int MaxOrganizationUsers { get; set; } = 0; // 0 = unlimited (Professional), 3 = SimpleStart limit } // Property & Tenant Lifecycle Enums diff --git a/0-Aquiis.Core/Entities/MaintenanceRequest.cs b/0-Aquiis.Core/Entities/MaintenanceRequest.cs index 1d4a508..6b0cca9 100644 --- a/0-Aquiis.Core/Entities/MaintenanceRequest.cs +++ b/0-Aquiis.Core/Entities/MaintenanceRequest.cs @@ -67,6 +67,23 @@ public class MaintenanceRequest : BaseModel, ISchedulableEntity public virtual Property? Property { get; set; } public virtual Lease? Lease { get; set; } + /// + /// Collection of repairs that comprise this maintenance request. + /// A MaintenanceRequest CONSISTS of one or more Repairs (composition relationship). + /// Professional product: MR must have at least one repair before completion. + /// + public virtual ICollection Repairs { get; set; } = new List(); + + // Computed properties for repair aggregation + [NotMapped] + public decimal TotalRepairCost => Repairs?.Sum(r => r.Cost) ?? 0; + + [NotMapped] + public int RepairCount => Repairs?.Count ?? 0; + + [NotMapped] + public int TotalRepairDuration => Repairs?.Sum(r => r.DurationMinutes) ?? 0; + // Computed property for days open [NotMapped] public int DaysOpen diff --git a/0-Aquiis.Core/Entities/Organization.cs b/0-Aquiis.Core/Entities/Organization.cs index d1521e9..6c4db00 100644 --- a/0-Aquiis.Core/Entities/Organization.cs +++ b/0-Aquiis.Core/Entities/Organization.cs @@ -41,7 +41,7 @@ public class Organization public bool IsDeleted { get; set; } = false; // Navigation properties - public virtual ICollection UserOrganizations { get; set; } = new List(); + public virtual ICollection OrganizationUsers { get; set; } = new List(); public virtual ICollection Properties { get; set; } = new List(); public virtual ICollection Tenants { get; set; } = new List(); public virtual ICollection Leases { get; set; } = new List(); diff --git a/0-Aquiis.Core/Entities/UserOrganization.cs b/0-Aquiis.Core/Entities/OrganizationUser.cs similarity index 95% rename from 0-Aquiis.Core/Entities/UserOrganization.cs rename to 0-Aquiis.Core/Entities/OrganizationUser.cs index 9789e98..aa881c5 100644 --- a/0-Aquiis.Core/Entities/UserOrganization.cs +++ b/0-Aquiis.Core/Entities/OrganizationUser.cs @@ -8,11 +8,11 @@ namespace Aquiis.Core.Entities /// /// Junction table for multi-organization user assignments with role-based permissions /// - public class UserOrganization + public class OrganizationUser { [RequiredGuid] - [Display(Name = "UserOrganization ID")] + [Display(Name = "OrganizationUser ID")] public Guid Id { get; set; } = Guid.NewGuid(); /// diff --git a/0-Aquiis.Core/Entities/Payment.cs b/0-Aquiis.Core/Entities/Payment.cs index 614580e..03e652d 100644 --- a/0-Aquiis.Core/Entities/Payment.cs +++ b/0-Aquiis.Core/Entities/Payment.cs @@ -10,6 +10,11 @@ public class Payment : BaseModel [Display(Name = "Organization ID")] public Guid OrganizationId { get; set; } = Guid.Empty; + [Required] + [StringLength(50)] + [Display(Name = "Payment Number")] + public string PaymentNumber { get; set; } = string.Empty; + [Required] public Guid InvoiceId { get; set; } diff --git a/0-Aquiis.Core/Entities/Property.cs b/0-Aquiis.Core/Entities/Property.cs index d6164cb..4279a11 100644 --- a/0-Aquiis.Core/Entities/Property.cs +++ b/0-Aquiis.Core/Entities/Property.cs @@ -124,6 +124,8 @@ public class Property : BaseModel // Navigation properties public virtual ICollection Leases { get; set; } = new List(); public virtual ICollection Documents { get; set; } = new List(); + public virtual ICollection Repairs { get; set; } = new List(); + public virtual ICollection MaintenanceRequests { get; set; } = new List(); // Computed property for pending application count [NotMapped] diff --git a/0-Aquiis.Core/Entities/Repair.cs b/0-Aquiis.Core/Entities/Repair.cs new file mode 100644 index 0000000..d6fd4dd --- /dev/null +++ b/0-Aquiis.Core/Entities/Repair.cs @@ -0,0 +1,134 @@ +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using Aquiis.Core.Validation; + +namespace Aquiis.Core.Entities; + +/// +/// Represents work performed on a property WITHOUT workflow/status tracking. +/// Repairs capture what work was done (or is being done) without the complexity +/// of MaintenanceRequest workflow (no Status, Priority, or Assignment). +/// Use CompletedOn to determine if work is finished (null = in progress, date = completed). +/// +public class Repair : BaseModel +{ + // Core Identity + [RequiredGuid] + [Display(Name = "Organization ID")] + public Guid OrganizationId { get; set; } = Guid.Empty; + + [RequiredGuid] + public Guid PropertyId { get; set; } + + // Optional Relationships (Soft References) + /// + /// Optional: Links this repair to a MaintenanceRequest workflow (Professional product). + /// Null for standalone repairs (SimpleStart product). + /// + public Guid? MaintenanceRequestId { get; set; } + + /// + /// Optional: Links this repair to a specific lease/tenant. + /// + public Guid? LeaseId { get; set; } + + // Repair Details + [Required] + [StringLength(200)] + [Display(Name = "Description")] + public string Description { get; set; } = string.Empty; + + [StringLength(50)] + [Display(Name = "Repair Type")] + public string RepairType { get; set; } = string.Empty; // From ApplicationConstants.RepairTypes + + /// + /// Optional: Date when work was actually completed. + /// Null = work in progress or not yet completed. + /// Date = work finished on this date. + /// Since Repairs have no Status field, CompletedOn provides definitive completion date. + /// + [Display(Name = "Completed On")] + public DateTime? CompletedOn { get; set; } + + // Cost & Duration + [Column(TypeName = "decimal(18,2)")] + [Display(Name = "Cost")] + public decimal Cost { get; set; } + + [Display(Name = "Duration (Minutes)")] + public int DurationMinutes { get; set; } // Time spent on repair + + // Who did the work + [StringLength(100)] + [Display(Name = "Contractor/Company Name")] + public string ContractorName { get; set; } = string.Empty; // Company or person name (e.g., "ABC Plumbing & Heating" or "John Doe") + + [StringLength(100)] + [Display(Name = "Contact Person")] + public string ContactPerson { get; set; } = string.Empty; // Specific person at company (optional for companies) + + [StringLength(20)] + [Display(Name = "Contractor Phone")] + public string ContractorPhone { get; set; } = string.Empty; // Optional: "555-1234" + + /// + /// Optional: Link to Contractor entity when contractor list is implemented. + /// When null, contractor details are stored in text fields (ContractorName/ContactPerson/ContractorPhone). + /// + [Display(Name = "Contractor ID")] + public Guid? ContractorId { get; set; } + + /// + /// Future: Link to formal Contact entity when added to the system. + /// + public Guid? ContactId { get; set; } + + // Additional Details + [StringLength(2000)] + [Display(Name = "Notes")] + public string Notes { get; set; } = string.Empty; + + [StringLength(500)] + [Display(Name = "Parts Replaced")] + public string PartsReplaced { get; set; } = string.Empty; // e.g., "Faucet cartridge, shower seal" + + [Display(Name = "Warranty Applies")] + public bool WarrantyApplies { get; set; } = false; + + [Display(Name = "Warranty Expires On")] + public DateTime? WarrantyExpiresOn { get; set; } + + // Navigation Properties + public virtual Property? Property { get; set; } + public virtual MaintenanceRequest? MaintenanceRequest { get; set; } + public virtual Lease? Lease { get; set; } + + // Computed Properties + [NotMapped] + [Display(Name = "Duration")] + public string DurationDisplay + { + get + { + if (DurationMinutes < 60) + return $"{DurationMinutes} minutes"; + + var hours = DurationMinutes / 60; + var minutes = DurationMinutes % 60; + return minutes > 0 + ? $"{hours}h {minutes}m" + : $"{hours} hour{(hours > 1 ? "s" : "")}"; + } + } + + [NotMapped] + [Display(Name = "Under Warranty")] + public bool IsUnderWarranty => WarrantyApplies && + WarrantyExpiresOn.HasValue && + WarrantyExpiresOn.Value > DateTime.Today; + + [NotMapped] + [Display(Name = "Completed")] + public bool IsCompleted => CompletedOn.HasValue; //Provides quick check for completion status. If no value, work is In Progess in the display. +} diff --git a/0-Aquiis.Core/Entities/UserProfile.cs b/0-Aquiis.Core/Entities/UserProfile.cs new file mode 100644 index 0000000..eb57330 --- /dev/null +++ b/0-Aquiis.Core/Entities/UserProfile.cs @@ -0,0 +1,54 @@ +using System; + +namespace Aquiis.Core.Entities; + +/// +/// User profile information stored in business context (ApplicationDbContext). +/// Separate from Identity (AspNetUsers) to enable single-context queries with business entities. +/// Email is denormalized for query simplification (considered read-only in B2B context). +/// +public class UserProfile : BaseModel +{ + /// + /// Foreign key to AspNetUsers.Id (Identity context). + /// This links the profile to the authentication user. + /// + public string UserId { get; set; } = string.Empty; + + // Personal Information (denormalized from Identity for query efficiency) + + /// + /// User's email address (cached from AspNetUsers). + /// Considered read-only - changes require sync with Identity table. + /// + public string Email { get; set; } = string.Empty; + + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public string? PhoneNumber { get; set; } + + // Organization Context + + /// + /// User's "home" organization - their primary/default organization. + /// + public Guid? OrganizationId { get; set; } + + /// + /// Currently active organization the user is viewing/working with. + /// Can differ from home organization for users with multi-org access. + /// + public Guid? ActiveOrganizationId { get; set; } + + // Computed Properties + + /// + /// Full name combining first and last name. + /// + public string FullName => $"{FirstName} {LastName}".Trim(); + + /// + /// Display name for UI - uses full name if available, falls back to email. + /// + public string DisplayName => string.IsNullOrWhiteSpace(FullName) ? Email : FullName; +} diff --git a/0-Aquiis.Core/Interfaces/Services/IUserContextService.cs b/0-Aquiis.Core/Interfaces/Services/IUserContextService.cs index 78ad844..8e1cfb6 100644 --- a/0-Aquiis.Core/Interfaces/Services/IUserContextService.cs +++ b/0-Aquiis.Core/Interfaces/Services/IUserContextService.cs @@ -1,3 +1,5 @@ +using Aquiis.Core.Entities; + namespace Aquiis.Core.Interfaces.Services; /// @@ -30,4 +32,27 @@ public interface IUserContextService /// Gets the current user's OrganizationId (DEPRECATED: Use GetActiveOrganizationIdAsync). /// Task GetOrganizationIdAsync(); + + /// + /// Forces a refresh of the cached user data. + /// Call this if user data has been updated and you need to reload it. + /// + Task RefreshAsync(); + + Task GetActiveOrganizationAsync(); + + Task GetCurrentOrganizationRoleAsync(); + + Task IsAccountOwnerAsync(); + + + /// + /// Switch the user's active organization + /// + Task SwitchOrganizationAsync(Guid organizationId); + + /// + /// Check if the current user has a specific permission in their active organization + /// + Task HasPermissionAsync(string permission); } \ No newline at end of file diff --git a/0-Aquiis.Core/Utilities/CalendarEventRouter.cs b/0-Aquiis.Core/Utilities/CalendarEventRouter.cs index 05050c5..e283663 100644 --- a/0-Aquiis.Core/Utilities/CalendarEventRouter.cs +++ b/0-Aquiis.Core/Utilities/CalendarEventRouter.cs @@ -19,9 +19,9 @@ public static class CalendarEventRouter return evt.SourceEntityType switch { - nameof(Tour) => $"/PropertyManagement/Tours/Details/{evt.SourceEntityId}", - nameof(Inspection) => $"/PropertyManagement/Inspections/View/{evt.SourceEntityId}", - nameof(MaintenanceRequest) => $"/PropertyManagement/Maintenance/View/{evt.SourceEntityId}", + nameof(Tour) => $"/PropertyManagement/Tours/{evt.SourceEntityId}", + nameof(Inspection) => $"/PropertyManagement/Inspections/{evt.SourceEntityId}", + nameof(MaintenanceRequest) => $"/PropertyManagement/Maintenance/{evt.SourceEntityId}", // Add new schedulable entity routes here as they are created _ => null }; diff --git a/0-Aquiis.Core/Utilities/StringSanitizer.cs b/0-Aquiis.Core/Utilities/StringSanitizer.cs new file mode 100644 index 0000000..bb5254b --- /dev/null +++ b/0-Aquiis.Core/Utilities/StringSanitizer.cs @@ -0,0 +1,97 @@ +namespace Aquiis.Core.Utilities; + +/// +/// Provides string sanitization and normalization utilities for consistent data storage. +/// +public static class StringSanitizer +{ + /// + /// Trims leading and trailing whitespace from a string. + /// Returns empty string if input is null or whitespace. + /// + public static string Trim(string? value) + { + return value?.Trim() ?? string.Empty; + } + + /// + /// Trims and converts to lowercase for case-insensitive comparisons. + /// Useful for emails, usernames, etc. + /// + public static string NormalizeForComparison(string? value) + { + return value?.Trim().ToLowerInvariant() ?? string.Empty; + } + + /// + /// Normalizes email addresses: trims and converts to lowercase. + /// + public static string NormalizeEmail(string? email) + { + return email?.Trim().ToLowerInvariant() ?? string.Empty; + } + + /// + /// Normalizes phone numbers: removes all non-digit characters. + /// Example: "(555) 123-4567" becomes "5551234567" + /// + public static string NormalizePhoneNumber(string? phoneNumber) + { + if (string.IsNullOrWhiteSpace(phoneNumber)) + return string.Empty; + + return new string(phoneNumber.Where(char.IsDigit).ToArray()); + } + + /// + /// Formats a normalized phone number for display. + /// Example: "5551234567" becomes "(555) 123-4567" + /// + public static string FormatPhoneNumber(string? phoneNumber) + { + var normalized = NormalizePhoneNumber(phoneNumber); + + if (normalized.Length == 10) + { + return $"({normalized.Substring(0, 3)}) {normalized.Substring(3, 3)}-{normalized.Substring(6, 4)}"; + } + else if (normalized.Length == 11 && normalized.StartsWith("1")) + { + return $"+1 ({normalized.Substring(1, 3)}) {normalized.Substring(4, 3)}-{normalized.Substring(7, 4)}"; + } + + return phoneNumber ?? string.Empty; + } + + /// + /// Collapses multiple consecutive spaces into a single space and trims. + /// Example: "Hello World " becomes "Hello World" + /// + public static string CollapseWhitespace(string? value) + { + if (string.IsNullOrWhiteSpace(value)) + return string.Empty; + + return string.Join(" ", value.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); + } + + /// + /// Removes all whitespace from a string. + /// Useful for IDs, codes, etc. + /// + public static string RemoveWhitespace(string? value) + { + if (string.IsNullOrWhiteSpace(value)) + return string.Empty; + + return new string(value.Where(c => !char.IsWhiteSpace(c)).ToArray()); + } + + /// + /// Sanitizes a string for safe display by trimming and collapsing whitespace. + /// + public static string Sanitize(string? value) + { + return CollapseWhitespace(value); + } +} diff --git a/0-Aquiis.Core/Validation/TrimAttribute.cs b/0-Aquiis.Core/Validation/TrimAttribute.cs new file mode 100644 index 0000000..522ed7a --- /dev/null +++ b/0-Aquiis.Core/Validation/TrimAttribute.cs @@ -0,0 +1,28 @@ +using System.ComponentModel.DataAnnotations; + +namespace Aquiis.Core.Validation; + +/// +/// Validation attribute that automatically trims string values during model binding. +/// Removes leading and trailing whitespace from the property value. +/// +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)] +public class TrimAttribute : ValidationAttribute +{ + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) + { + if (value is string stringValue && !string.IsNullOrEmpty(stringValue)) + { + var trimmedValue = stringValue.Trim(); + + // Use reflection to set the trimmed value back to the property + var propertyInfo = validationContext.ObjectType.GetProperty(validationContext.MemberName!); + if (propertyInfo != null && propertyInfo.CanWrite) + { + propertyInfo.SetValue(validationContext.ObjectInstance, trimmedValue); + } + } + + return ValidationResult.Success; + } +} diff --git a/1-Aquiis.Infrastructure/Data/ApplicationDbContext.cs b/1-Aquiis.Infrastructure/Data/ApplicationDbContext.cs index 825dad4..47b36fa 100644 --- a/1-Aquiis.Infrastructure/Data/ApplicationDbContext.cs +++ b/1-Aquiis.Infrastructure/Data/ApplicationDbContext.cs @@ -16,6 +16,40 @@ public ApplicationDbContext(DbContextOptions options) { } + public override int SaveChanges() + { + SanitizeStringProperties(); + return base.SaveChanges(); + } + + public override Task SaveChangesAsync(CancellationToken cancellationToken = default) + { + SanitizeStringProperties(); + return base.SaveChangesAsync(cancellationToken); + } + + private void SanitizeStringProperties() + { + var entries = ChangeTracker.Entries() + .Where(e => e.State == EntityState.Added || e.State == EntityState.Modified); + + foreach (var entry in entries) + { + foreach (var property in entry.Properties) + { + if (property.Metadata.ClrType == typeof(string) && property.CurrentValue != null) + { + var value = property.CurrentValue as string; + if (!string.IsNullOrEmpty(value)) + { + // Trim leading/trailing whitespace + property.CurrentValue = value.Trim(); + } + } + } + } + } + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); @@ -35,6 +69,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) public DbSet Documents { get; set; } public DbSet Inspections { get; set; } public DbSet MaintenanceRequests { get; set; } + public DbSet Repairs { get; set; } public DbSet OrganizationSettings { get; set; } public DbSet SchemaVersions { get; set; } public DbSet ChecklistTemplates { get; set; } @@ -54,7 +89,10 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) // Multi-organization support public DbSet Organizations { get; set; } - public DbSet UserOrganizations { get; set; } + public DbSet OrganizationUsers { get; set; } + + // User profiles (business context - separate from Identity) + public DbSet UserProfiles { get; set; } // Workflow audit logging public DbSet WorkflowAuditLogs { get; set; } @@ -234,7 +272,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasOne(m => m.Property) - .WithMany() + .WithMany(p => p.MaintenanceRequests) .HasForeignKey(m => m.PropertyId) .OnDelete(DeleteBehavior.Restrict); @@ -252,6 +290,39 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.HasIndex(e => e.RequestedOn); }); + // Configure Repair entity + modelBuilder.Entity(entity => + { + // Required relationship: Property (Restrict - can't delete property with repairs) + entity.HasOne(r => r.Property) + .WithMany(p => p.Repairs) + .HasForeignKey(r => r.PropertyId) + .OnDelete(DeleteBehavior.Restrict); + + // Optional relationship: MaintenanceRequest (SetNull - repairs can outlive MR) + entity.HasOne(r => r.MaintenanceRequest) + .WithMany(mr => mr.Repairs) + .HasForeignKey(r => r.MaintenanceRequestId) + .OnDelete(DeleteBehavior.SetNull); + + // Optional relationship: Lease (SetNull - repairs can outlive lease) + entity.HasOne(r => r.Lease) + .WithMany() + .HasForeignKey(r => r.LeaseId) + .OnDelete(DeleteBehavior.SetNull); + + // Decimal precision for Cost field + entity.Property(e => e.Cost).HasPrecision(18, 2); + + // Indexes for query optimization + entity.HasIndex(e => e.OrganizationId); + entity.HasIndex(e => e.PropertyId); + entity.HasIndex(e => e.MaintenanceRequestId); + entity.HasIndex(e => e.LeaseId); + entity.HasIndex(e => e.CompletedOn); + entity.HasIndex(e => e.RepairType); + }); + // Configure OrganizationSettings entity modelBuilder.Entity(entity => { @@ -499,13 +570,13 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) // No navigation property configured here }); - // Configure UserOrganization entity - modelBuilder.Entity(entity => + // Configure OrganizationUser entity + modelBuilder.Entity(entity => { entity.HasKey(e => e.Id); entity.HasOne(uo => uo.Organization) - .WithMany(o => o.UserOrganizations) + .WithMany(o => o.OrganizationUsers) .HasForeignKey(uo => uo.OrganizationId) .OnDelete(DeleteBehavior.Cascade); @@ -607,6 +678,24 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.CostPerSMS).HasPrecision(18, 4); }); + // Configure UserProfile entity + modelBuilder.Entity(entity => + { + entity.HasKey(e => e.Id); + + // Unique constraint: one profile per user + entity.HasIndex(e => e.UserId).IsUnique(); + + // Additional indexes for common queries + entity.HasIndex(e => e.Email); + entity.HasIndex(e => e.OrganizationId); + entity.HasIndex(e => e.ActiveOrganizationId); + entity.HasIndex(e => e.IsDeleted); + + // Note: No navigation property to AspNetUsers (different context) + // UserId is a string FK to Identity context, but no EF relationship configured + }); + // Seed System Checklist Templates SeedChecklistTemplates(modelBuilder); } diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.Designer.cs index 7cc048d..0a34aa3 100644 --- a/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.Designer.cs +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.Designer.cs @@ -3263,7 +3263,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("Tours"); }); - modelBuilder.Entity("Aquiis.Core.Entities.UserOrganization", b => + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -3320,7 +3320,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.HasIndex("UserId", "OrganizationId") .IsUnique(); - b.ToTable("UserOrganizations"); + b.ToTable("OrganizationUsers"); }); modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => @@ -3937,10 +3937,10 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("ProspectiveTenant"); }); - modelBuilder.Entity("Aquiis.Core.Entities.UserOrganization", b => + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => { b.HasOne("Aquiis.Core.Entities.Organization", "Organization") - .WithMany("UserOrganizations") + .WithMany("OrganizationUsers") .HasForeignKey("OrganizationId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -3991,7 +3991,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("Tenants"); - b.Navigation("UserOrganizations"); + b.Navigation("OrganizationUsers"); }); modelBuilder.Entity("Aquiis.Core.Entities.Property", b => diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.cs index 5257751..cc241fc 100644 --- a/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.cs +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260104205822_InitialCreate.cs @@ -481,7 +481,7 @@ protected override void Up(MigrationBuilder migrationBuilder) }); migrationBuilder.CreateTable( - name: "UserOrganizations", + name: "OrganizationUsers", columns: table => new { Id = table.Column(type: "TEXT", nullable: false), @@ -500,9 +500,9 @@ protected override void Up(MigrationBuilder migrationBuilder) }, constraints: table => { - table.PrimaryKey("PK_UserOrganizations", x => x.Id); + table.PrimaryKey("PK_OrganizationUsers", x => x.Id); table.ForeignKey( - name: "FK_UserOrganizations_Organizations_OrganizationId", + name: "FK_OrganizationUsers_Organizations_OrganizationId", column: x => x.OrganizationId, principalTable: "Organizations", principalColumn: "Id", @@ -1839,23 +1839,23 @@ protected override void Up(MigrationBuilder migrationBuilder) column: "Status"); migrationBuilder.CreateIndex( - name: "IX_UserOrganizations_IsActive", - table: "UserOrganizations", + name: "IX_OrganizationUsers_IsActive", + table: "OrganizationUsers", column: "IsActive"); migrationBuilder.CreateIndex( - name: "IX_UserOrganizations_OrganizationId", - table: "UserOrganizations", + name: "IX_OrganizationUsers_OrganizationId", + table: "OrganizationUsers", column: "OrganizationId"); migrationBuilder.CreateIndex( - name: "IX_UserOrganizations_Role", - table: "UserOrganizations", + name: "IX_OrganizationUsers_Role", + table: "OrganizationUsers", column: "Role"); migrationBuilder.CreateIndex( - name: "IX_UserOrganizations_UserId_OrganizationId", - table: "UserOrganizations", + name: "IX_OrganizationUsers_UserId_OrganizationId", + table: "OrganizationUsers", columns: new[] { "UserId", "OrganizationId" }, unique: true); @@ -2018,7 +2018,7 @@ protected override void Down(MigrationBuilder migrationBuilder) name: "Tours"); migrationBuilder.DropTable( - name: "UserOrganizations"); + name: "OrganizationUsers"); migrationBuilder.DropTable( name: "WorkflowAuditLogs"); diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.Designer.cs new file mode 100644 index 0000000..2cb376c --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.Designer.cs @@ -0,0 +1,4097 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260114233331_AddUserProfileTable")] + partial class AddUserProfileTable + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.cs new file mode 100644 index 0000000..1fc7e3b --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260114233331_AddUserProfileTable.cs @@ -0,0 +1,71 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class AddUserProfileTable : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "UserProfiles", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + UserId = table.Column(type: "TEXT", nullable: false), + Email = table.Column(type: "TEXT", nullable: false), + FirstName = table.Column(type: "TEXT", nullable: false), + LastName = table.Column(type: "TEXT", nullable: false), + PhoneNumber = table.Column(type: "TEXT", nullable: true), + OrganizationId = table.Column(type: "TEXT", nullable: true), + ActiveOrganizationId = table.Column(type: "TEXT", nullable: true), + CreatedOn = table.Column(type: "TEXT", nullable: false), + CreatedBy = table.Column(type: "TEXT", maxLength: 100, nullable: false), + LastModifiedOn = table.Column(type: "TEXT", nullable: true), + LastModifiedBy = table.Column(type: "TEXT", maxLength: 100, nullable: true), + IsDeleted = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_UserProfiles", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_UserProfiles_ActiveOrganizationId", + table: "UserProfiles", + column: "ActiveOrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_UserProfiles_Email", + table: "UserProfiles", + column: "Email"); + + migrationBuilder.CreateIndex( + name: "IX_UserProfiles_IsDeleted", + table: "UserProfiles", + column: "IsDeleted"); + + migrationBuilder.CreateIndex( + name: "IX_UserProfiles_OrganizationId", + table: "UserProfiles", + column: "OrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_UserProfiles_UserId", + table: "UserProfiles", + column: "UserId", + unique: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "UserProfiles"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.Designer.cs new file mode 100644 index 0000000..a8ad23e --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.Designer.cs @@ -0,0 +1,4102 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260117025048_AddPaymentNumberField")] + partial class AddPaymentNumberField + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.cs new file mode 100644 index 0000000..dcf4007 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260117025048_AddPaymentNumberField.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class AddPaymentNumberField : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "PaymentNumber", + table: "Payments", + type: "TEXT", + maxLength: 50, + nullable: false, + defaultValue: ""); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "PaymentNumber", + table: "Payments"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.Designer.cs new file mode 100644 index 0000000..07e1479 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.Designer.cs @@ -0,0 +1,4238 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260122142531_AddRepairEntity")] + partial class AddRepairEntity + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("ContactId") + .HasColumnType("TEXT"); + + b.Property("ContractorName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Cost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MaintenanceRequestId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PartsReplaced") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RepairType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("WarrantyApplies") + .HasColumnType("INTEGER"); + + b.Property("WarrantyExpiresOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("LeaseId"); + + b.HasIndex("MaintenanceRequestId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RepairType"); + + b.ToTable("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.MaintenanceRequest", "MaintenanceRequest") + .WithMany("Repairs") + .HasForeignKey("MaintenanceRequestId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("MaintenanceRequest"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.cs new file mode 100644 index 0000000..d353785 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260122142531_AddRepairEntity.cs @@ -0,0 +1,103 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class AddRepairEntity : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Repairs", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + OrganizationId = table.Column(type: "TEXT", nullable: false), + PropertyId = table.Column(type: "TEXT", nullable: false), + MaintenanceRequestId = table.Column(type: "TEXT", nullable: true), + LeaseId = table.Column(type: "TEXT", nullable: true), + Description = table.Column(type: "TEXT", maxLength: 200, nullable: false), + RepairType = table.Column(type: "TEXT", maxLength: 50, nullable: false), + CompletedOn = table.Column(type: "TEXT", nullable: true), + Cost = table.Column(type: "decimal(18,2)", precision: 18, scale: 2, nullable: false), + DurationMinutes = table.Column(type: "INTEGER", nullable: false), + CompletedBy = table.Column(type: "TEXT", maxLength: 100, nullable: false), + ContractorName = table.Column(type: "TEXT", maxLength: 100, nullable: false), + ContractorPhone = table.Column(type: "TEXT", maxLength: 20, nullable: false), + ContactId = table.Column(type: "TEXT", nullable: true), + Notes = table.Column(type: "TEXT", maxLength: 2000, nullable: false), + PartsReplaced = table.Column(type: "TEXT", maxLength: 500, nullable: false), + WarrantyApplies = table.Column(type: "INTEGER", nullable: false), + WarrantyExpiresOn = table.Column(type: "TEXT", nullable: true), + CreatedOn = table.Column(type: "TEXT", nullable: false), + CreatedBy = table.Column(type: "TEXT", maxLength: 100, nullable: false), + LastModifiedOn = table.Column(type: "TEXT", nullable: true), + LastModifiedBy = table.Column(type: "TEXT", maxLength: 100, nullable: true), + IsDeleted = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Repairs", x => x.Id); + table.ForeignKey( + name: "FK_Repairs_Leases_LeaseId", + column: x => x.LeaseId, + principalTable: "Leases", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_Repairs_MaintenanceRequests_MaintenanceRequestId", + column: x => x.MaintenanceRequestId, + principalTable: "MaintenanceRequests", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + table.ForeignKey( + name: "FK_Repairs_Properties_PropertyId", + column: x => x.PropertyId, + principalTable: "Properties", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_CompletedOn", + table: "Repairs", + column: "CompletedOn"); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_LeaseId", + table: "Repairs", + column: "LeaseId"); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_MaintenanceRequestId", + table: "Repairs", + column: "MaintenanceRequestId"); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_OrganizationId", + table: "Repairs", + column: "OrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_PropertyId", + table: "Repairs", + column: "PropertyId"); + + migrationBuilder.CreateIndex( + name: "IX_Repairs_RepairType", + table: "Repairs", + column: "RepairType"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Repairs"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.Designer.cs new file mode 100644 index 0000000..9c64e1d --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.Designer.cs @@ -0,0 +1,4241 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260122152750_RenameCompletedByToContactPersonAndAddContractorId")] + partial class RenameCompletedByToContactPersonAndAddContractorId + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("ContactId") + .HasColumnType("TEXT"); + + b.Property("ContactPerson") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorId") + .HasColumnType("TEXT"); + + b.Property("ContractorName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Cost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MaintenanceRequestId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PartsReplaced") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RepairType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("WarrantyApplies") + .HasColumnType("INTEGER"); + + b.Property("WarrantyExpiresOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("LeaseId"); + + b.HasIndex("MaintenanceRequestId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RepairType"); + + b.ToTable("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.MaintenanceRequest", "MaintenanceRequest") + .WithMany("Repairs") + .HasForeignKey("MaintenanceRequestId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("MaintenanceRequest"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.cs new file mode 100644 index 0000000..5a7a776 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260122152750_RenameCompletedByToContactPersonAndAddContractorId.cs @@ -0,0 +1,39 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class RenameCompletedByToContactPersonAndAddContractorId : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.RenameColumn( + name: "CompletedBy", + table: "Repairs", + newName: "ContactPerson"); + + migrationBuilder.AddColumn( + name: "ContractorId", + table: "Repairs", + type: "TEXT", + nullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ContractorId", + table: "Repairs"); + + migrationBuilder.RenameColumn( + name: "ContactPerson", + table: "Repairs", + newName: "CompletedBy"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.Designer.cs new file mode 100644 index 0000000..afd2770 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.Designer.cs @@ -0,0 +1,4314 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260127184357_AddTestEntityAndPropertyTestField")] + partial class AddTestEntityAndPropertyTestField + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TestField") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("ContactId") + .HasColumnType("TEXT"); + + b.Property("ContactPerson") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorId") + .HasColumnType("TEXT"); + + b.Property("ContractorName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Cost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MaintenanceRequestId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PartsReplaced") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RepairType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("WarrantyApplies") + .HasColumnType("INTEGER"); + + b.Property("WarrantyExpiresOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("LeaseId"); + + b.HasIndex("MaintenanceRequestId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RepairType"); + + b.ToTable("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.TestEntity", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("TestDate") + .HasColumnType("TEXT"); + + b.Property("TestDescription") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("TestFlag") + .HasColumnType("INTEGER"); + + b.Property("TestName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("TestNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("TestName"); + + b.ToTable("TestEntities"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("MaintenanceRequests") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.MaintenanceRequest", "MaintenanceRequest") + .WithMany("Repairs") + .HasForeignKey("MaintenanceRequestId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Repairs") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("MaintenanceRequest"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.TestEntity", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + + b.Navigation("MaintenanceRequests"); + + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.cs new file mode 100644 index 0000000..281ef18 --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260127184357_AddTestEntityAndPropertyTestField.cs @@ -0,0 +1,76 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class AddTestEntityAndPropertyTestField : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TestField", + table: "Properties", + type: "TEXT", + maxLength: 100, + nullable: true); + + migrationBuilder.CreateTable( + name: "TestEntities", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + OrganizationId = table.Column(type: "TEXT", maxLength: 100, nullable: false), + TestName = table.Column(type: "TEXT", maxLength: 200, nullable: false), + TestDescription = table.Column(type: "TEXT", maxLength: 500, nullable: true), + TestDate = table.Column(type: "TEXT", nullable: true), + TestNumber = table.Column(type: "INTEGER", nullable: false), + TestFlag = table.Column(type: "INTEGER", nullable: false), + CreatedOn = table.Column(type: "TEXT", nullable: false), + CreatedBy = table.Column(type: "TEXT", maxLength: 100, nullable: false), + LastModifiedOn = table.Column(type: "TEXT", nullable: true), + LastModifiedBy = table.Column(type: "TEXT", maxLength: 100, nullable: true), + IsDeleted = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TestEntities", x => x.Id); + table.ForeignKey( + name: "FK_TestEntities_Organizations_OrganizationId", + column: x => x.OrganizationId, + principalTable: "Organizations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_IsDeleted", + table: "TestEntities", + column: "IsDeleted"); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_OrganizationId", + table: "TestEntities", + column: "OrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_TestName", + table: "TestEntities", + column: "TestName"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TestEntities"); + + migrationBuilder.DropColumn( + name: "TestField", + table: "Properties"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.Designer.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.Designer.cs new file mode 100644 index 0000000..da1b16c --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.Designer.cs @@ -0,0 +1,4245 @@ +// +using System; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20260127190738_RemoveTestEntityAndPropertyTestField")] + partial class RemoveTestEntityAndPropertyTestField + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("BackgroundCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("BackgroundCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckCompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreditCheckNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("CreditCheckPassed") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequested") + .HasColumnType("INTEGER"); + + b.Property("CreditCheckRequestedOn") + .HasColumnType("TEXT"); + + b.Property("CreditScore") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OverallResult") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("ResultNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OverallResult"); + + b.HasIndex("RentalApplicationId") + .IsUnique(); + + b.ToTable("ApplicationScreenings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Color") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("EndOn") + .HasColumnType("TEXT"); + + b.Property("EventType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Icon") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Location") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityId") + .HasColumnType("TEXT"); + + b.Property("SourceEntityType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("StartOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("EventType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("SourceEntityId"); + + b.HasIndex("StartOn"); + + b.HasIndex("SourceEntityType", "SourceEntityId"); + + b.ToTable("CalendarEvents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AutoCreateEvents") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultColor") + .HasColumnType("TEXT"); + + b.Property("DefaultIcon") + .HasColumnType("TEXT"); + + b.Property("DisplayOrder") + .HasColumnType("INTEGER"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ShowOnCalendar") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("OrganizationId", "EntityType") + .IsUnique(); + + b.ToTable("CalendarSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("ChecklistType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CompletedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.HasIndex("ChecklistType"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("Status"); + + b.ToTable("Checklists"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsChecked") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhotoUrl") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.ToTable("ChecklistItems"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSystemTemplate") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("OrganizationId"); + + b.ToTable("ChecklistTemplates"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0001-000000000001"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Standard property showing checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Property Tour", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000002"), + Category = "MoveIn", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-in inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-In", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000003"), + Category = "MoveOut", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Move-out inspection checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Move-Out", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }, + new + { + Id = new Guid("00000000-0000-0000-0001-000000000004"), + Category = "Tour", + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + Description = "Open house event checklist", + IsDeleted = false, + IsSystemTemplate = true, + Name = "Open House", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000") + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowsNotes") + .HasColumnType("INTEGER"); + + b.Property("CategorySection") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ChecklistTemplateId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRequired") + .HasColumnType("INTEGER"); + + b.Property("ItemOrder") + .HasColumnType("INTEGER"); + + b.Property("ItemText") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RequiresValue") + .HasColumnType("INTEGER"); + + b.Property("SectionOrder") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistTemplateId"); + + b.ToTable("ChecklistTemplateItems"); + + b.HasData( + new + { + Id = new Guid("00000000-0000-0000-0002-000000000001"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Greeted prospect and verified appointment", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000002"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Reviewed property exterior and curb appeal", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000003"), + AllowsNotes = true, + CategorySection = "Arrival & Introduction", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Showed parking area/garage", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000004"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 4, + ItemText = "Toured living room/common areas", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000005"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 5, + ItemText = "Showed all bedrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000006"), + AllowsNotes = true, + CategorySection = "Interior Tour", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 6, + ItemText = "Showed all bathrooms", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 2 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000007"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 7, + ItemText = "Toured kitchen and demonstrated appliances", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000008"), + AllowsNotes = true, + CategorySection = "Kitchen & Appliances", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 8, + ItemText = "Explained which appliances are included", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 3 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000009"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 9, + ItemText = "Explained HVAC system and thermostat controls", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000010"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 10, + ItemText = "Reviewed utility responsibilities (tenant vs landlord)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000011"), + AllowsNotes = true, + CategorySection = "Utilities & Systems", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 11, + ItemText = "Showed water heater location", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 4 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000012"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 12, + ItemText = "Showed storage areas (closets, attic, basement)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000013"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 13, + ItemText = "Showed laundry facilities", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000014"), + AllowsNotes = true, + CategorySection = "Storage & Amenities", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 14, + ItemText = "Showed outdoor space (yard, patio, balcony)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 5 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000015"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 15, + ItemText = "Discussed monthly rent amount", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000016"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 16, + ItemText = "Explained security deposit and move-in costs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000017"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 17, + ItemText = "Reviewed lease term length and start date", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000018"), + AllowsNotes = true, + CategorySection = "Lease Terms", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 18, + ItemText = "Explained pet policy", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 6 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000019"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 19, + ItemText = "Explained application process and requirements", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000020"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 20, + ItemText = "Reviewed screening process (background, credit check)", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000021"), + AllowsNotes = true, + CategorySection = "Next Steps", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 21, + ItemText = "Answered all prospect questions", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 7 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000022"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 22, + ItemText = "Prospect Interest Level", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = true, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000023"), + AllowsNotes = true, + CategorySection = "Assessment", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000001"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 23, + ItemText = "Overall showing feedback and notes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 8 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000024"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Document property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000025"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect keys and access codes", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000026"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000002"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Review lease terms with tenant", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000027"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Inspect property condition", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000028"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Collect all keys and access devices", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000029"), + AllowsNotes = true, + CategorySection = "General", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000003"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Document damages and needed repairs", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000030"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 1, + ItemText = "Set up signage and directional markers", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000031"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 2, + ItemText = "Prepare information packets", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }, + new + { + Id = new Guid("00000000-0000-0000-0002-000000000032"), + AllowsNotes = true, + CategorySection = "Preparation", + ChecklistTemplateId = new Guid("00000000-0000-0000-0001-000000000004"), + CreatedBy = "", + CreatedOn = new DateTime(2025, 11, 30, 0, 0, 0, 0, DateTimeKind.Utc), + IsDeleted = false, + IsRequired = true, + ItemOrder = 3, + ItemText = "Set up visitor sign-in sheet", + OrganizationId = new Guid("00000000-0000-0000-0000-000000000000"), + RequiresValue = false, + SectionOrder = 1 + }); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("DocumentType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("FileData") + .IsRequired() + .HasColumnType("BLOB"); + + b.Property("FileExtension") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FilePath") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("FileSize") + .HasColumnType("INTEGER"); + + b.Property("FileType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PaymentId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Documents"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActionItemsRequired") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("BathroomSinkGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomSinkNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomToiletGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomToiletNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomTubShowerGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomTubShowerNotes") + .HasColumnType("TEXT"); + + b.Property("BathroomVentilationGood") + .HasColumnType("INTEGER"); + + b.Property("BathroomVentilationNotes") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CarbonMonoxideDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("CarbonMonoxideDetectorsNotes") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("ElectricalSystemGood") + .HasColumnType("INTEGER"); + + b.Property("ElectricalSystemNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorFoundationGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorFoundationNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorGuttersGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorGuttersNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorRoofGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorRoofNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorSidingGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorSidingNotes") + .HasColumnType("TEXT"); + + b.Property("ExteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("ExteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("GeneralNotes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("HvacSystemGood") + .HasColumnType("INTEGER"); + + b.Property("HvacSystemNotes") + .HasColumnType("TEXT"); + + b.Property("InspectedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("InspectionType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InteriorCeilingsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorCeilingsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorDoorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorDoorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorFloorsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorFloorsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWallsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWallsNotes") + .HasColumnType("TEXT"); + + b.Property("InteriorWindowsGood") + .HasColumnType("INTEGER"); + + b.Property("InteriorWindowsNotes") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenAppliancesNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCabinetsGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCabinetsNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenCountersGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenCountersNotes") + .HasColumnType("TEXT"); + + b.Property("KitchenSinkPlumbingGood") + .HasColumnType("INTEGER"); + + b.Property("KitchenSinkPlumbingNotes") + .HasColumnType("TEXT"); + + b.Property("LandscapingGood") + .HasColumnType("INTEGER"); + + b.Property("LandscapingNotes") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OverallCondition") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PlumbingSystemGood") + .HasColumnType("INTEGER"); + + b.Property("PlumbingSystemNotes") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("SmokeDetectorsGood") + .HasColumnType("INTEGER"); + + b.Property("SmokeDetectorsNotes") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("DocumentId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("PropertyId"); + + b.ToTable("Inspections"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AmountPaid") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("DueOn") + .HasColumnType("TEXT"); + + b.Property("InvoiceNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("InvoicedOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAmount") + .HasColumnType("decimal(18,2)"); + + b.Property("LateFeeApplied") + .HasColumnType("INTEGER"); + + b.Property("LateFeeAppliedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("ReminderSent") + .HasColumnType("INTEGER"); + + b.Property("ReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceNumber") + .IsUnique(); + + b.HasIndex("LeaseId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DeclinedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpectedMoveOutDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseOfferId") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PreviousLeaseId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProposedRenewalRent") + .HasColumnType("decimal(18,2)"); + + b.Property("RenewalNotes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("RenewalNotificationSent") + .HasColumnType("INTEGER"); + + b.Property("RenewalNotificationSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalNumber") + .HasColumnType("INTEGER"); + + b.Property("RenewalOfferedOn") + .HasColumnType("TEXT"); + + b.Property("RenewalReminderSentOn") + .HasColumnType("TEXT"); + + b.Property("RenewalResponseOn") + .HasColumnType("TEXT"); + + b.Property("RenewalStatus") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("SignedOn") + .HasColumnType("TEXT"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TerminationNoticedOn") + .HasColumnType("TEXT"); + + b.Property("TerminationReason") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("TenantId"); + + b.ToTable("Leases"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConvertedLeaseId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EndDate") + .HasColumnType("TEXT"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasColumnType("decimal(18,2)"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OfferedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("RentalApplicationId") + .HasColumnType("TEXT"); + + b.Property("RespondedOn") + .HasColumnType("TEXT"); + + b.Property("ResponseNotes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SecurityDeposit") + .HasColumnType("decimal(18,2)"); + + b.Property("StartDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Terms") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("RentalApplicationId"); + + b.ToTable("LeaseOffers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActualCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("AssignedTo") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("EstimatedCost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Priority") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RequestedBy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("RequestedByEmail") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("RequestedByPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("RequestedOn") + .HasColumnType("TEXT"); + + b.Property("ResolutionNotes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("LeaseId"); + + b.HasIndex("Priority"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RequestedOn"); + + b.HasIndex("Status"); + + b.ToTable("MaintenanceRequests"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Note", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasMaxLength(5000) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("UserFullName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Notes"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyDigestTime") + .HasColumnType("TEXT"); + + b.Property("EmailAddress") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmailApplicationStatusChange") + .HasColumnType("INTEGER"); + + b.Property("EmailInspectionScheduled") + .HasColumnType("INTEGER"); + + b.Property("EmailLeaseExpiring") + .HasColumnType("INTEGER"); + + b.Property("EmailMaintenanceUpdate") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("EmailPaymentReceived") + .HasColumnType("INTEGER"); + + b.Property("EnableDailyDigest") + .HasColumnType("INTEGER"); + + b.Property("EnableEmailNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableInAppNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableSMSNotifications") + .HasColumnType("INTEGER"); + + b.Property("EnableWeeklyDigest") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("SMSLeaseExpiringUrgent") + .HasColumnType("INTEGER"); + + b.Property("SMSMaintenanceEmergency") + .HasColumnType("INTEGER"); + + b.Property("SMSPaymentDue") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("WeeklyDigestDay") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("NotificationPreferences"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("State") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OwnerId"); + + b.ToTable("Organizations"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("DailyLimit") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("EmailsSentToday") + .HasColumnType("INTEGER"); + + b.Property("EnableSsl") + .HasColumnType("INTEGER"); + + b.Property("FromEmail") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FromName") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsEmailEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastEmailSentOn") + .HasColumnType("TEXT"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastErrorOn") + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyLimit") + .HasColumnType("INTEGER"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PlanType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("SendGridApiKeyEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("SmtpPort") + .HasColumnType("INTEGER"); + + b.Property("SmtpServer") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationEmailSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccountBalance") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("AccountType") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CostPerSMS") + .HasPrecision(18, 4) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DailyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsSMSEnabled") + .HasColumnType("INTEGER"); + + b.Property("IsVerified") + .HasColumnType("INTEGER"); + + b.Property("LastError") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastSMSSentOn") + .HasColumnType("TEXT"); + + b.Property("LastVerifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyCountResetOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ProviderName") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("SMSSentThisMonth") + .HasColumnType("INTEGER"); + + b.Property("SMSSentToday") + .HasColumnType("INTEGER"); + + b.Property("StatsLastUpdatedOn") + .HasColumnType("TEXT"); + + b.Property("TwilioAccountSidEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioAuthTokenEncrypted") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("TwilioPhoneNumber") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSMSSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSettings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AllowTenantDividendChoice") + .HasColumnType("INTEGER"); + + b.Property("ApplicationExpirationDays") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("AutoCalculateSecurityDeposit") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DefaultApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("DefaultDividendPaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("DividendDistributionMonth") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LateFeeAutoApply") + .HasColumnType("INTEGER"); + + b.Property("LateFeeEnabled") + .HasColumnType("INTEGER"); + + b.Property("LateFeeGracePeriodDays") + .HasColumnType("INTEGER"); + + b.Property("LateFeePercentage") + .HasPrecision(5, 4) + .HasColumnType("TEXT"); + + b.Property("MaxLateFeeAmount") + .HasPrecision(18, 2) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("PaymentReminderDaysBefore") + .HasColumnType("INTEGER"); + + b.Property("PaymentReminderEnabled") + .HasColumnType("INTEGER"); + + b.Property("RefundProcessingDays") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositInvestmentEnabled") + .HasColumnType("INTEGER"); + + b.Property("SecurityDepositMultiplier") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TourNoShowGracePeriodHours") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationSettings"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DocumentId") + .HasColumnType("TEXT"); + + b.Property("InvoiceId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaidOn") + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("DocumentId"); + + b.HasIndex("InvoiceId"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Address") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Bathrooms") + .HasMaxLength(3) + .HasColumnType("decimal(3,1)"); + + b.Property("Bedrooms") + .HasMaxLength(3) + .HasColumnType("INTEGER"); + + b.Property("City") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("IsAvailable") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastRoutineInspectionDate") + .HasColumnType("TEXT"); + + b.Property("MonthlyRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("NextRoutineInspectionDueDate") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RoutineInspectionIntervalMonths") + .HasColumnType("INTEGER"); + + b.Property("SquareFeet") + .HasMaxLength(7) + .HasColumnType("INTEGER"); + + b.Property("State") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("UnitNumber") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("ZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Address"); + + b.HasIndex("OrganizationId"); + + b.ToTable("Properties"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("DesiredMoveInDate") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("FirstContactedOn") + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationState") + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("InterestedPropertyId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Source") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("InterestedPropertyId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.ToTable("ProspectiveTenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ApplicationFee") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ApplicationFeePaid") + .HasColumnType("INTEGER"); + + b.Property("ApplicationFeePaidOn") + .HasColumnType("TEXT"); + + b.Property("ApplicationFeePaymentMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("CurrentAddress") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("CurrentCity") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CurrentRent") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CurrentState") + .IsRequired() + .HasMaxLength(2) + .HasColumnType("TEXT"); + + b.Property("CurrentZipCode") + .IsRequired() + .HasMaxLength(10) + .HasColumnType("TEXT"); + + b.Property("DecidedOn") + .HasColumnType("TEXT"); + + b.Property("DecisionBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("DenialReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("EmployerName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmploymentLengthMonths") + .HasColumnType("INTEGER"); + + b.Property("ExpiresOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("JobTitle") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LandlordName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("LandlordPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("MonthlyIncome") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("Reference1Name") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference1Phone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference1Relationship") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Reference2Name") + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Reference2Phone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Reference2Relationship") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AppliedOn"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("Status"); + + b.ToTable("RentalApplications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("ContactId") + .HasColumnType("TEXT"); + + b.Property("ContactPerson") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorId") + .HasColumnType("TEXT"); + + b.Property("ContractorName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Cost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MaintenanceRequestId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PartsReplaced") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RepairType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("WarrantyApplies") + .HasColumnType("INTEGER"); + + b.Property("WarrantyExpiresOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("LeaseId"); + + b.HasIndex("MaintenanceRequestId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RepairType"); + + b.ToTable("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AppliedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("SchemaVersions"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Amount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateReceived") + .HasColumnType("TEXT"); + + b.Property("DeductionsAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DeductionsReason") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("InInvestmentPool") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PoolEntryDate") + .HasColumnType("TEXT"); + + b.Property("PoolExitDate") + .HasColumnType("TEXT"); + + b.Property("RefundAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("RefundMethod") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("RefundProcessedDate") + .HasColumnType("TEXT"); + + b.Property("RefundReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("TransactionReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("InInvestmentPool"); + + b.HasIndex("LeaseId") + .IsUnique(); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.ToTable("SecurityDeposits"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("BaseDividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("ChoiceMadeOn") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendAmount") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("InvestmentPoolId") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MailingAddress") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("MonthsInPool") + .HasColumnType("INTEGER"); + + b.Property("Notes") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("PaymentMethod") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("PaymentProcessedOn") + .HasColumnType("TEXT"); + + b.Property("PaymentReference") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ProrationFactor") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("SecurityDepositId") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantId") + .HasColumnType("TEXT"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("InvestmentPoolId"); + + b.HasIndex("LeaseId"); + + b.HasIndex("SecurityDepositId"); + + b.HasIndex("Status"); + + b.HasIndex("TenantId"); + + b.HasIndex("Year"); + + b.ToTable("SecurityDepositDividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveLeaseCount") + .HasColumnType("INTEGER"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendPerLease") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("DividendsCalculatedOn") + .HasColumnType("TEXT"); + + b.Property("DividendsDistributedOn") + .HasColumnType("TEXT"); + + b.Property("EndingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Notes") + .HasMaxLength(1000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("OrganizationShare") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("OrganizationSharePercentage") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("ReturnRate") + .HasPrecision(18, 6) + .HasColumnType("decimal(18,6)"); + + b.Property("StartingBalance") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("TenantShareTotal") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("TotalEarnings") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("Year") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Status"); + + b.HasIndex("Year") + .IsUnique(); + + b.ToTable("SecurityDepositInvestmentPools"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DateOfBirth") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactName") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("EmergencyContactPhone") + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IdentificationNumber") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Email") + .IsUnique(); + + b.HasIndex("IdentificationNumber") + .IsUnique(); + + b.HasIndex("OrganizationId"); + + b.ToTable("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CalendarEventId") + .HasColumnType("TEXT"); + + b.Property("ChecklistId") + .HasColumnType("TEXT"); + + b.Property("ConductedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("Feedback") + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("InterestLevel") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("ProspectiveTenantId") + .HasColumnType("TEXT"); + + b.Property("ScheduledOn") + .HasColumnType("TEXT"); + + b.Property("Status") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ChecklistId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("ProspectiveTenantId"); + + b.HasIndex("ScheduledOn"); + + b.HasIndex("Status"); + + b.ToTable("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FirstName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LastName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ActiveOrganizationId"); + + b.HasIndex("Email"); + + b.HasIndex("IsDeleted"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") + .IsUnique(); + + b.ToTable("UserProfiles"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Action") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EntityId") + .HasColumnType("TEXT"); + + b.Property("EntityType") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FromStatus") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Metadata") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PerformedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("PerformedOn") + .HasColumnType("TEXT"); + + b.Property("Reason") + .HasColumnType("TEXT"); + + b.Property("ToStatus") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Action"); + + b.HasIndex("EntityId"); + + b.HasIndex("EntityType"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PerformedBy"); + + b.HasIndex("PerformedOn"); + + b.HasIndex("EntityType", "EntityId"); + + b.ToTable("WorkflowAuditLogs"); + }); + + modelBuilder.Entity("Notification", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Category") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("EmailError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("EmailSent") + .HasColumnType("INTEGER"); + + b.Property("EmailSentOn") + .HasColumnType("TEXT"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("IsRead") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("Message") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("ReadOn") + .HasColumnType("TEXT"); + + b.Property("RecipientUserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("RelatedEntityId") + .HasColumnType("TEXT"); + + b.Property("RelatedEntityType") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("SMSError") + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("SMSSent") + .HasColumnType("INTEGER"); + + b.Property("SMSSentOn") + .HasColumnType("TEXT"); + + b.Property("SendEmail") + .HasColumnType("INTEGER"); + + b.Property("SendInApp") + .HasColumnType("INTEGER"); + + b.Property("SendSMS") + .HasColumnType("INTEGER"); + + b.Property("SentOn") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Category"); + + b.HasIndex("IsRead"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("RecipientUserId"); + + b.HasIndex("SentOn"); + + b.ToTable("Notifications"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => + { + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithOne("Screening") + .HasForeignKey("Aquiis.Core.Entities.ApplicationScreening", "RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.CalendarEvent", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Checklists") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict); + + b.Navigation("ChecklistTemplate"); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistItem", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany("Items") + .HasForeignKey("ChecklistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Checklist"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplateItem", b => + { + b.HasOne("Aquiis.Core.Entities.ChecklistTemplate", "ChecklistTemplate") + .WithMany("Items") + .HasForeignKey("ChecklistTemplateId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChecklistTemplate"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Document", b => + { + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany() + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Documents") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Payment", "Payment") + .WithMany() + .HasForeignKey("PaymentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Documents") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("Invoice"); + + b.Navigation("Lease"); + + b.Navigation("Payment"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Inspection", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany("Invoices") + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Lease"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Leases") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Leases") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany("Leases") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Property"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.LeaseOffer", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany() + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.RentalApplication", "RentalApplication") + .WithMany() + .HasForeignKey("RentalApplicationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + + b.Navigation("RentalApplication"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("MaintenanceRequests") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.NotificationPreferences", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationEmailSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationSMSSettings", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => + { + b.HasOne("Aquiis.Core.Entities.Document", "Document") + .WithMany() + .HasForeignKey("DocumentId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Invoice", "Invoice") + .WithMany("Payments") + .HasForeignKey("InvoiceId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Document"); + + b.Navigation("Invoice"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Properties") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "InterestedProperty") + .WithMany() + .HasForeignKey("InterestedPropertyId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("InterestedProperty"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Applications") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.MaintenanceRequest", "MaintenanceRequest") + .WithMany("Repairs") + .HasForeignKey("MaintenanceRequestId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Repairs") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("MaintenanceRequest"); + + b.Navigation("Property"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositDividend", b => + { + b.HasOne("Aquiis.Core.Entities.SecurityDepositInvestmentPool", "InvestmentPool") + .WithMany("Dividends") + .HasForeignKey("InvestmentPoolId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.SecurityDeposit", "SecurityDeposit") + .WithMany("Dividends") + .HasForeignKey("SecurityDepositId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.Tenant", "Tenant") + .WithMany() + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("InvestmentPool"); + + b.Navigation("Lease"); + + b.Navigation("SecurityDeposit"); + + b.Navigation("Tenant"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", null) + .WithMany("Tenants") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.NoAction) + .IsRequired(); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tour", b => + { + b.HasOne("Aquiis.Core.Entities.Checklist", "Checklist") + .WithMany() + .HasForeignKey("ChecklistId"); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany() + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.HasOne("Aquiis.Core.Entities.ProspectiveTenant", "ProspectiveTenant") + .WithMany("Tours") + .HasForeignKey("ProspectiveTenantId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Checklist"); + + b.Navigation("Property"); + + b.Navigation("ProspectiveTenant"); + }); + + modelBuilder.Entity("Notification", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany() + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Checklist", b => + { + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ChecklistTemplate", b => + { + b.Navigation("Checklists"); + + b.Navigation("Items"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Invoice", b => + { + b.Navigation("Payments"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Lease", b => + { + b.Navigation("Documents"); + + b.Navigation("Invoices"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => + { + b.Navigation("Leases"); + + b.Navigation("OrganizationUsers"); + + b.Navigation("Properties"); + + b.Navigation("Tenants"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Property", b => + { + b.Navigation("Documents"); + + b.Navigation("Leases"); + + b.Navigation("MaintenanceRequests"); + + b.Navigation("Repairs"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => + { + b.Navigation("Applications"); + + b.Navigation("Tours"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.RentalApplication", b => + { + b.Navigation("Screening"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDepositInvestmentPool", b => + { + b.Navigation("Dividends"); + }); + + modelBuilder.Entity("Aquiis.Core.Entities.Tenant", b => + { + b.Navigation("Leases"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.cs b/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.cs new file mode 100644 index 0000000..8a1c80e --- /dev/null +++ b/1-Aquiis.Infrastructure/Data/Migrations/20260127190738_RemoveTestEntityAndPropertyTestField.cs @@ -0,0 +1,76 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Aquiis.Infrastructure.Data.Migrations +{ + /// + public partial class RemoveTestEntityAndPropertyTestField : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "TestEntities"); + + migrationBuilder.DropColumn( + name: "TestField", + table: "Properties"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "TestField", + table: "Properties", + type: "TEXT", + maxLength: 100, + nullable: true); + + migrationBuilder.CreateTable( + name: "TestEntities", + columns: table => new + { + Id = table.Column(type: "TEXT", nullable: false), + CreatedBy = table.Column(type: "TEXT", maxLength: 100, nullable: false), + CreatedOn = table.Column(type: "TEXT", nullable: false), + IsDeleted = table.Column(type: "INTEGER", nullable: false), + LastModifiedBy = table.Column(type: "TEXT", maxLength: 100, nullable: true), + LastModifiedOn = table.Column(type: "TEXT", nullable: true), + OrganizationId = table.Column(type: "TEXT", maxLength: 100, nullable: false), + TestDate = table.Column(type: "TEXT", nullable: true), + TestDescription = table.Column(type: "TEXT", maxLength: 500, nullable: true), + TestFlag = table.Column(type: "INTEGER", nullable: false), + TestName = table.Column(type: "TEXT", maxLength: 200, nullable: false), + TestNumber = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TestEntities", x => x.Id); + table.ForeignKey( + name: "FK_TestEntities_Organizations_OrganizationId", + column: x => x.OrganizationId, + principalTable: "Organizations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_IsDeleted", + table: "TestEntities", + column: "IsDeleted"); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_OrganizationId", + table: "TestEntities", + column: "OrganizationId"); + + migrationBuilder.CreateIndex( + name: "IX_TestEntities_TestName", + table: "TestEntities", + column: "TestName"); + } + } +} diff --git a/1-Aquiis.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs b/1-Aquiis.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs index 5eb5864..095e216 100644 --- a/1-Aquiis.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/1-Aquiis.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs @@ -15,7 +15,7 @@ partial class ApplicationDbContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "9.0.11"); + modelBuilder.HasAnnotation("ProductVersion", "10.0.1"); modelBuilder.Entity("Aquiis.Core.Entities.ApplicationScreening", b => { @@ -2355,6 +2355,66 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("OrganizationSettings"); }); + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("CreatedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("GrantedBy") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("GrantedOn") + .HasColumnType("TEXT"); + + b.Property("IsActive") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("RevokedOn") + .HasColumnType("TEXT"); + + b.Property("Role") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IsActive"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("Role"); + + b.HasIndex("UserId", "OrganizationId") + .IsUnique(); + + b.ToTable("OrganizationUsers"); + }); + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => { b.Property("Id") @@ -2405,6 +2465,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(50) .HasColumnType("TEXT"); + b.Property("PaymentNumber") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + b.HasKey("Id"); b.HasIndex("DocumentId"); @@ -2774,6 +2839,115 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("RentalApplications"); }); + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("CompletedOn") + .HasColumnType("TEXT"); + + b.Property("ContactId") + .HasColumnType("TEXT"); + + b.Property("ContactPerson") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorId") + .HasColumnType("TEXT"); + + b.Property("ContractorName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("ContractorPhone") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("TEXT"); + + b.Property("Cost") + .HasPrecision(18, 2) + .HasColumnType("decimal(18,2)"); + + b.Property("CreatedBy") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("CreatedOn") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(200) + .HasColumnType("TEXT"); + + b.Property("DurationMinutes") + .HasColumnType("INTEGER"); + + b.Property("IsDeleted") + .HasColumnType("INTEGER"); + + b.Property("LastModifiedBy") + .HasMaxLength(100) + .HasColumnType("TEXT"); + + b.Property("LastModifiedOn") + .HasColumnType("TEXT"); + + b.Property("LeaseId") + .HasColumnType("TEXT"); + + b.Property("MaintenanceRequestId") + .HasColumnType("TEXT"); + + b.Property("Notes") + .IsRequired() + .HasMaxLength(2000) + .HasColumnType("TEXT"); + + b.Property("OrganizationId") + .HasColumnType("TEXT"); + + b.Property("PartsReplaced") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("TEXT"); + + b.Property("PropertyId") + .HasColumnType("TEXT"); + + b.Property("RepairType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("WarrantyApplies") + .HasColumnType("INTEGER"); + + b.Property("WarrantyExpiresOn") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CompletedOn"); + + b.HasIndex("LeaseId"); + + b.HasIndex("MaintenanceRequestId"); + + b.HasIndex("OrganizationId"); + + b.HasIndex("PropertyId"); + + b.HasIndex("RepairType"); + + b.ToTable("Repairs"); + }); + modelBuilder.Entity("Aquiis.Core.Entities.SchemaVersion", b => { b.Property("Id") @@ -3260,46 +3434,48 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Tours"); }); - modelBuilder.Entity("Aquiis.Core.Entities.UserOrganization", b => + modelBuilder.Entity("Aquiis.Core.Entities.UserProfile", b => { b.Property("Id") - .ValueGeneratedOnAdd() + .HasColumnType("TEXT"); + + b.Property("ActiveOrganizationId") .HasColumnType("TEXT"); b.Property("CreatedBy") .IsRequired() + .HasMaxLength(100) .HasColumnType("TEXT"); b.Property("CreatedOn") .HasColumnType("TEXT"); - b.Property("GrantedBy") + b.Property("Email") .IsRequired() .HasColumnType("TEXT"); - b.Property("GrantedOn") + b.Property("FirstName") + .IsRequired() .HasColumnType("TEXT"); - b.Property("IsActive") - .HasColumnType("INTEGER"); - b.Property("IsDeleted") .HasColumnType("INTEGER"); b.Property("LastModifiedBy") + .HasMaxLength(100) .HasColumnType("TEXT"); b.Property("LastModifiedOn") .HasColumnType("TEXT"); - b.Property("OrganizationId") + b.Property("LastName") + .IsRequired() .HasColumnType("TEXT"); - b.Property("RevokedOn") + b.Property("OrganizationId") .HasColumnType("TEXT"); - b.Property("Role") - .IsRequired() + b.Property("PhoneNumber") .HasColumnType("TEXT"); b.Property("UserId") @@ -3308,16 +3484,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("IsActive"); + b.HasIndex("ActiveOrganizationId"); - b.HasIndex("OrganizationId"); + b.HasIndex("Email"); - b.HasIndex("Role"); + b.HasIndex("IsDeleted"); - b.HasIndex("UserId", "OrganizationId") + b.HasIndex("OrganizationId"); + + b.HasIndex("UserId") .IsUnique(); - b.ToTable("UserOrganizations"); + b.ToTable("UserProfiles"); }); modelBuilder.Entity("Aquiis.Core.Entities.WorkflowAuditLog", b => @@ -3741,7 +3919,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) .OnDelete(DeleteBehavior.SetNull); b.HasOne("Aquiis.Core.Entities.Property", "Property") - .WithMany() + .WithMany("MaintenanceRequests") .HasForeignKey("PropertyId") .OnDelete(DeleteBehavior.Restrict) .IsRequired(); @@ -3784,6 +3962,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Organization"); }); + modelBuilder.Entity("Aquiis.Core.Entities.OrganizationUser", b => + { + b.HasOne("Aquiis.Core.Entities.Organization", "Organization") + .WithMany("OrganizationUsers") + .HasForeignKey("OrganizationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Organization"); + }); + modelBuilder.Entity("Aquiis.Core.Entities.Payment", b => { b.HasOne("Aquiis.Core.Entities.Document", "Document") @@ -3846,6 +4035,31 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ProspectiveTenant"); }); + modelBuilder.Entity("Aquiis.Core.Entities.Repair", b => + { + b.HasOne("Aquiis.Core.Entities.Lease", "Lease") + .WithMany() + .HasForeignKey("LeaseId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.MaintenanceRequest", "MaintenanceRequest") + .WithMany("Repairs") + .HasForeignKey("MaintenanceRequestId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("Aquiis.Core.Entities.Property", "Property") + .WithMany("Repairs") + .HasForeignKey("PropertyId") + .OnDelete(DeleteBehavior.Restrict) + .IsRequired(); + + b.Navigation("Lease"); + + b.Navigation("MaintenanceRequest"); + + b.Navigation("Property"); + }); + modelBuilder.Entity("Aquiis.Core.Entities.SecurityDeposit", b => { b.HasOne("Aquiis.Core.Entities.Lease", "Lease") @@ -3934,17 +4148,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("ProspectiveTenant"); }); - modelBuilder.Entity("Aquiis.Core.Entities.UserOrganization", b => - { - b.HasOne("Aquiis.Core.Entities.Organization", "Organization") - .WithMany("UserOrganizations") - .HasForeignKey("OrganizationId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Organization"); - }); - modelBuilder.Entity("Notification", b => { b.HasOne("Aquiis.Core.Entities.Organization", "Organization") @@ -3980,15 +4183,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Invoices"); }); + modelBuilder.Entity("Aquiis.Core.Entities.MaintenanceRequest", b => + { + b.Navigation("Repairs"); + }); + modelBuilder.Entity("Aquiis.Core.Entities.Organization", b => { b.Navigation("Leases"); + b.Navigation("OrganizationUsers"); + b.Navigation("Properties"); b.Navigation("Tenants"); - - b.Navigation("UserOrganizations"); }); modelBuilder.Entity("Aquiis.Core.Entities.Property", b => @@ -3996,6 +4204,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("Documents"); b.Navigation("Leases"); + + b.Navigation("MaintenanceRequests"); + + b.Navigation("Repairs"); }); modelBuilder.Entity("Aquiis.Core.Entities.ProspectiveTenant", b => diff --git a/2-Aquiis.Application/DependencyInjection.cs b/2-Aquiis.Application/DependencyInjection.cs index e5dd138..943c938 100644 --- a/2-Aquiis.Application/DependencyInjection.cs +++ b/2-Aquiis.Application/DependencyInjection.cs @@ -1,4 +1,5 @@ using Aquiis.Application.Services; +using Aquiis.Application.Services.PdfGenerators; using Aquiis.Application.Services.Workflows; using Aquiis.Infrastructure; using Microsoft.Extensions.DependencyInjection; @@ -37,6 +38,7 @@ public static IServiceCollection AddApplication( services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -49,6 +51,7 @@ public static IServiceCollection AddApplication( services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/2-Aquiis.Application/Services/CalendarEventService.cs b/2-Aquiis.Application/Services/CalendarEventService.cs index 09aeb29..573b6ee 100644 --- a/2-Aquiis.Application/Services/CalendarEventService.cs +++ b/2-Aquiis.Application/Services/CalendarEventService.cs @@ -142,12 +142,28 @@ public async Task> GetEventsAsync( /// public async Task CreateCustomEventAsync(CalendarEvent calendarEvent) { - calendarEvent.EventType = CalendarEventTypes.Custom; + // Service sets tracking fields - UI should not set these + var organizationId = await _userContextService.GetActiveOrganizationIdAsync(); + var userId = await _userContextService.GetUserIdAsync(); + + calendarEvent.Id = Guid.NewGuid(); + calendarEvent.OrganizationId = organizationId ?? Guid.Empty; + calendarEvent.CreatedBy = userId ?? string.Empty; + calendarEvent.CreatedOn = DateTime.UtcNow; + + // Not linked to a source entity (user-created from calendar UI) calendarEvent.SourceEntityId = null; calendarEvent.SourceEntityType = null; - calendarEvent.Color = CalendarEventTypes.GetColor(CalendarEventTypes.Custom); - calendarEvent.Icon = CalendarEventTypes.GetIcon(CalendarEventTypes.Custom); - calendarEvent.CreatedOn = DateTime.UtcNow; + + // Set color and icon from event type if not already set + if (string.IsNullOrEmpty(calendarEvent.Color)) + { + calendarEvent.Color = CalendarEventTypes.GetColor(calendarEvent.EventType ?? CalendarEventTypes.Custom); + } + if (string.IsNullOrEmpty(calendarEvent.Icon)) + { + calendarEvent.Icon = CalendarEventTypes.GetIcon(calendarEvent.EventType ?? CalendarEventTypes.Custom); + } _context.CalendarEvents.Add(calendarEvent); await _context.SaveChangesAsync(); @@ -160,9 +176,12 @@ public async Task CreateCustomEventAsync(CalendarEvent calendarEv /// public async Task UpdateCustomEventAsync(CalendarEvent calendarEvent) { + var organizationId = await _userContextService.GetActiveOrganizationIdAsync(); + var userId = await _userContextService.GetUserIdAsync(); + var existing = await _context.CalendarEvents .FirstOrDefaultAsync(e => e.Id == calendarEvent.Id - && e.OrganizationId == calendarEvent.OrganizationId + && e.OrganizationId == organizationId && e.SourceEntityType == null && !e.IsDeleted); @@ -176,8 +195,10 @@ public async Task CreateCustomEventAsync(CalendarEvent calendarEv existing.PropertyId = calendarEvent.PropertyId; existing.Location = calendarEvent.Location; existing.Status = calendarEvent.Status; - existing.LastModifiedBy = calendarEvent.LastModifiedBy; - existing.LastModifiedOn = calendarEvent.LastModifiedOn; + + // Service sets tracking fields + existing.LastModifiedBy = userId ?? string.Empty; + existing.LastModifiedOn = DateTime.UtcNow; await _context.SaveChangesAsync(); diff --git a/2-Aquiis.Application/Services/DocumentNotificationService.cs b/2-Aquiis.Application/Services/DocumentNotificationService.cs index 06ce32b..fbdcf99 100644 --- a/2-Aquiis.Application/Services/DocumentNotificationService.cs +++ b/2-Aquiis.Application/Services/DocumentNotificationService.cs @@ -47,7 +47,7 @@ public async Task CheckDocumentExpirationsAsync() foreach (var organizationId in organizations) { // Get admin users for this organization - var adminUsers = await _dbContext.UserOrganizations + var adminUsers = await _dbContext.OrganizationUsers .Where(uom => uom.OrganizationId == organizationId && uom.Role == "Admin" && !uom.IsDeleted) diff --git a/2-Aquiis.Application/Services/InspectionService.cs b/2-Aquiis.Application/Services/InspectionService.cs index dd4b945..8a20dfb 100644 --- a/2-Aquiis.Application/Services/InspectionService.cs +++ b/2-Aquiis.Application/Services/InspectionService.cs @@ -2,7 +2,6 @@ using Aquiis.Core.Constants; using Aquiis.Core.Entities; using Aquiis.Core.Interfaces; -using Aquiis.Application.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -115,6 +114,25 @@ public async Task> GetByPropertyIdAsync(Guid propertyId) .ToListAsync(); } + /// + /// Gets the most recent routine inspection for a property. + /// + public async Task GetLastRoutineInspectionAsync(Guid propertyId) + { + var organizationId = await GetActiveOrganizationIdAsync(); + + return await _context.Inspections + .Include(i => i.Property) + .Include(i => i.Lease) + .ThenInclude(l => l!.Tenant) + .Where(i => i.PropertyId == propertyId + && i.InspectionType == ApplicationConstants.InspectionTypes.Routine + && !i.IsDeleted + && i.OrganizationId == organizationId) + .OrderByDescending(i => i.CompletedOn) + .FirstOrDefaultAsync(); + } + /// /// Gets a single inspection by ID with related data. /// diff --git a/2-Aquiis.Application/Services/LeaseService.cs b/2-Aquiis.Application/Services/LeaseService.cs index b129647..3b2d26a 100644 --- a/2-Aquiis.Application/Services/LeaseService.cs +++ b/2-Aquiis.Application/Services/LeaseService.cs @@ -110,6 +110,38 @@ public override async Task CreateAsync(Lease entity) var property = await _context.Properties.FindAsync(entity.PropertyId); if (property != null) { + property.Status = ApplicationConstants.PropertyStatuses.Occupied; + property.IsAvailable = false; + property.LastModifiedOn = DateTime.UtcNow; + property.LastModifiedBy = await _userContext.GetUserIdAsync(); + _context.Properties.Update(property); + await _context.SaveChangesAsync(); + } + } + + return lease; + } + + /// + /// Updates a lease and manages property status based on lease status changes. + /// + public override async Task UpdateAsync(Lease entity) + { + // Get the existing lease to check for status changes + var existingLease = await _context.Leases.AsNoTracking() + .FirstOrDefaultAsync(l => l.Id == entity.Id); + + var lease = await base.UpdateAsync(entity); + + // Handle property status when lease becomes active + if (existingLease != null && + existingLease.Status != ApplicationConstants.LeaseStatuses.Active && + entity.Status == ApplicationConstants.LeaseStatuses.Active) + { + var property = await _context.Properties.FindAsync(entity.PropertyId); + if (property != null) + { + property.Status = ApplicationConstants.PropertyStatuses.Occupied; property.IsAvailable = false; property.LastModifiedOn = DateTime.UtcNow; property.LastModifiedBy = await _userContext.GetUserIdAsync(); @@ -178,6 +210,7 @@ public override async Task DeleteAsync(Guid id) .Include(l => l.Document) .Include(l => l.Documents) .Include(l => l.Invoices) + .ThenInclude(i => i.Payments) .Where(l => l.Id == leaseId && !l.IsDeleted && l.Property.OrganizationId == organizationId) @@ -205,7 +238,7 @@ public async Task> GetLeasesWithRelationsAsync() .Include(l => l.Property) .Include(l => l.Tenant) .Where(l => !l.IsDeleted && l.Property.OrganizationId == organizationId) - .OrderByDescending(l => l.CreatedOn) + .OrderByDescending(l => l.StartDate) .ToListAsync(); } catch (Exception ex) diff --git a/2-Aquiis.Application/Services/NotificationService.cs b/2-Aquiis.Application/Services/NotificationService.cs index cc5275d..5e9c7fd 100644 --- a/2-Aquiis.Application/Services/NotificationService.cs +++ b/2-Aquiis.Application/Services/NotificationService.cs @@ -116,8 +116,8 @@ public async Task NotifyAllUsersAsync( Guid? relatedEntityId = null, string? relatedEntityType = null) { - // Query users through UserOrganizations to find all users in the organization - var userIds = await _context.UserOrganizations + // Query users through OrganizationUsers to find all users in the organization + var userIds = await _context.OrganizationUsers .Where(uo => uo.OrganizationId == organizationId && uo.IsActive && !uo.IsDeleted) .Select(uo => uo.UserId) .ToListAsync(); diff --git a/2-Aquiis.Application/Services/OrganizationService.cs b/2-Aquiis.Application/Services/OrganizationService.cs index 9605793..cd6d59d 100644 --- a/2-Aquiis.Application/Services/OrganizationService.cs +++ b/2-Aquiis.Application/Services/OrganizationService.cs @@ -2,6 +2,7 @@ using Aquiis.Core.Constants; using Aquiis.Core.Interfaces.Services; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; namespace Aquiis.Application.Services { @@ -9,11 +10,16 @@ public class OrganizationService { private readonly ApplicationDbContext _dbContext; private readonly IUserContextService _userContext; + private readonly ApplicationSettings _settings; - public OrganizationService(ApplicationDbContext dbContext, IUserContextService userContextService) + public OrganizationService( + ApplicationDbContext dbContext, + IUserContextService userContextService, + IOptions settings) { _dbContext = dbContext; _userContext = userContextService; + _settings = settings.Value; } #region CRUD Operations @@ -37,8 +43,8 @@ public async Task CreateOrganizationAsync(string ownerId, string n _dbContext.Organizations.Add(organization); - // Create Owner entry in UserOrganizations - var userOrganization = new UserOrganization + // Create Owner entry in OrganizationUsers + var OrganizationUser = new OrganizationUser { Id = Guid.NewGuid(), UserId = ownerId, @@ -51,7 +57,7 @@ public async Task CreateOrganizationAsync(string ownerId, string n CreatedBy = ownerId }; - _dbContext.UserOrganizations.Add(userOrganization); + _dbContext.OrganizationUsers.Add(OrganizationUser); // add organization settings record with defaults var settings = new OrganizationSettings @@ -96,8 +102,8 @@ public async Task CreateOrganizationAsync(Organization organizatio _dbContext.Organizations.Add(organization); - // Create Owner entry in UserOrganizations - var userOrganization = new UserOrganization + // Create Owner entry in OrganizationUsers + var OrganizationUser = new OrganizationUser { Id = Guid.NewGuid(), UserId = userId, @@ -110,7 +116,7 @@ public async Task CreateOrganizationAsync(Organization organizatio CreatedBy = userId }; - _dbContext.UserOrganizations.Add(userOrganization); + _dbContext.OrganizationUsers.Add(OrganizationUser); await _dbContext.SaveChangesAsync(); // add organization settings record with defaults @@ -143,7 +149,7 @@ public async Task CreateOrganizationAsync(Organization organizatio public async Task GetOrganizationByIdAsync(Guid organizationId) { return await _dbContext.Organizations - .Include(o => o.UserOrganizations) + .Include(o => o.OrganizationUsers) .FirstOrDefaultAsync(o => o.Id == organizationId && !o.IsDeleted); } @@ -159,11 +165,11 @@ public async Task> GetOwnedOrganizationsAsync(string userId) } /// - /// Get all organizations a user has access to (via UserOrganizations) + /// Get all organizations a user has access to (via OrganizationUsers) /// - public async Task> GetUserOrganizationsAsync(string userId) + public async Task> GetOrganizationUsersAsync(string userId) { - return await _dbContext.UserOrganizations + return await _dbContext.OrganizationUsers .Include(uo => uo.Organization) .Where(uo => uo.UserId == userId && uo.IsActive && !uo.IsDeleted) .Where(uo => !uo.Organization.IsDeleted) @@ -205,8 +211,8 @@ public async Task DeleteOrganizationAsync(Guid organizationId, string dele organization.LastModifiedOn = DateTime.UtcNow; organization.LastModifiedBy = deletedBy; - // Soft delete all UserOrganizations entries - var userOrgs = await _dbContext.UserOrganizations + // Soft delete all OrganizationUsers entries + var userOrgs = await _dbContext.OrganizationUsers .Where(uo => uo.OrganizationId == organizationId) .ToListAsync(); @@ -250,7 +256,7 @@ public async Task IsAdministratorAsync(string userId, Guid organizationId) /// public async Task CanAccessOrganizationAsync(string userId, Guid organizationId) { - return await _dbContext.UserOrganizations + return await _dbContext.OrganizationUsers .AnyAsync(uo => uo.UserId == userId && uo.OrganizationId == organizationId && uo.IsActive @@ -262,7 +268,7 @@ public async Task CanAccessOrganizationAsync(string userId, Guid organizat /// public async Task GetUserRoleForOrganizationAsync(string userId, Guid organizationId) { - var userOrg = await _dbContext.UserOrganizations + var userOrg = await _dbContext.OrganizationUsers .FirstOrDefaultAsync(uo => uo.UserId == userId && uo.OrganizationId == organizationId && uo.IsActive @@ -289,8 +295,26 @@ public async Task GrantOrganizationAccessAsync(string userId, Guid organiz if (organization == null || organization.IsDeleted) return false; + // Check user limit for SimpleStart (MaxOrganizationUsers > 0) + if (_settings.MaxOrganizationUsers > 0) + { + var currentUserCount = await _dbContext.OrganizationUsers + .Where(ou => ou.OrganizationId == organizationId + && ou.UserId != ApplicationConstants.SystemUser.Id + && ou.IsActive + && !ou.IsDeleted) + .CountAsync(); + + if (currentUserCount >= _settings.MaxOrganizationUsers) + { + throw new InvalidOperationException( + $"User limit reached. SimpleStart allows maximum {_settings.MaxOrganizationUsers} user accounts (including system account). " + + "Upgrade to Aquiis Professional for unlimited users."); + } + } + // Check if user already has access - var existing = await _dbContext.UserOrganizations + var existing = await _dbContext.OrganizationUsers .FirstOrDefaultAsync(uo => uo.UserId == userId && uo.OrganizationId == organizationId); if (existing != null) @@ -314,7 +338,7 @@ public async Task GrantOrganizationAccessAsync(string userId, Guid organiz else { // Create new access - var userOrganization = new UserOrganization + var OrganizationUser = new OrganizationUser { Id = Guid.NewGuid(), UserId = userId, @@ -327,7 +351,7 @@ public async Task GrantOrganizationAccessAsync(string userId, Guid organiz CreatedBy = grantedBy }; - _dbContext.UserOrganizations.Add(userOrganization); + _dbContext.OrganizationUsers.Add(OrganizationUser); } await _dbContext.SaveChangesAsync(); @@ -339,7 +363,7 @@ public async Task GrantOrganizationAccessAsync(string userId, Guid organiz /// public async Task RevokeOrganizationAccessAsync(string userId, Guid organizationId, string revokedBy) { - var userOrg = await _dbContext.UserOrganizations + var userOrg = await _dbContext.OrganizationUsers .FirstOrDefaultAsync(uo => uo.UserId == userId && uo.OrganizationId == organizationId && uo.IsActive); @@ -373,7 +397,7 @@ public async Task UpdateUserRoleAsync(string userId, Guid organizationId, if (!ApplicationConstants.OrganizationRoles.IsValid(newRole)) throw new ArgumentException($"Invalid role: {newRole}"); - var userOrg = await _dbContext.UserOrganizations + var userOrg = await _dbContext.OrganizationUsers .FirstOrDefaultAsync(uo => uo.UserId == userId && uo.OrganizationId == organizationId && uo.IsActive @@ -401,9 +425,9 @@ public async Task UpdateUserRoleAsync(string userId, Guid organizationId, /// /// Get all users with access to an organization /// - public async Task> GetOrganizationUsersAsync(Guid organizationId) + public async Task> GetOrganizationUsersAsync(Guid organizationId) { - return await _dbContext.UserOrganizations + return await _dbContext.OrganizationUsers .Where(uo => uo.OrganizationId == organizationId && uo.IsActive && !uo.IsDeleted && uo.UserId != ApplicationConstants.SystemUser.Id) .OrderBy(uo => uo.Role) .ThenBy(uo => uo.UserId) @@ -413,13 +437,13 @@ public async Task> GetOrganizationUsersAsync(Guid organiz /// /// Get all organization assignments for a user (including revoked) /// - public async Task> GetUserAssignmentsAsync() + public async Task> GetUserAssignmentsAsync() { var userId = await _userContext.GetUserIdAsync(); if (string.IsNullOrEmpty(userId)) throw new InvalidOperationException("Cannot get user assignments: User ID is not available in context."); - return await _dbContext.UserOrganizations + return await _dbContext.OrganizationUsers .Include(uo => uo.Organization) .Where(uo => uo.UserId == userId && !uo.IsDeleted && uo.UserId != ApplicationConstants.SystemUser.Id) .OrderByDescending(uo => uo.IsActive) @@ -430,13 +454,13 @@ public async Task> GetUserAssignmentsAsync() /// /// Get all organization assignments for a user (including revoked) /// - public async Task> GetActiveUserAssignmentsAsync() + public async Task> GetActiveUserAssignmentsAsync() { var userId = await _userContext.GetUserIdAsync(); if (string.IsNullOrEmpty(userId)) throw new InvalidOperationException("Cannot get user assignments: User ID is not available in context."); - return await _dbContext.UserOrganizations + return await _dbContext.OrganizationUsers .Include(uo => uo.Organization) .Where(uo => uo.UserId == userId && !uo.IsDeleted && uo.IsActive && uo.UserId != ApplicationConstants.SystemUser.Id) .OrderByDescending(uo => uo.IsActive) diff --git a/2-Aquiis.Application/Services/PaymentService.cs b/2-Aquiis.Application/Services/PaymentService.cs index 9c10a33..11993e4 100644 --- a/2-Aquiis.Application/Services/PaymentService.cs +++ b/2-Aquiis.Application/Services/PaymentService.cs @@ -77,7 +77,8 @@ protected override async Task ValidateEntityAsync(Payment entity) .SumAsync(p => p.Amount); var totalWithThisPayment = existingPayments + entity.Amount; - var invoiceTotal = invoice.Amount + (invoice.LateFeeAmount ?? 0); + // Invoice amount already includes late fees (added by ScheduledTaskService) + var invoiceTotal = invoice.Amount; if (totalWithThisPayment > invoiceTotal) { @@ -105,6 +106,12 @@ protected override async Task ValidateEntityAsync(Payment entity) /// public override async Task CreateAsync(Payment entity) { + // Auto-generate payment number if not provided + if (string.IsNullOrWhiteSpace(entity.PaymentNumber)) + { + entity.PaymentNumber = await GeneratePaymentNumberAsync(); + } + var payment = await base.CreateAsync(entity); await UpdateInvoiceAfterPaymentChangeAsync(payment.InvoiceId); return payment; @@ -252,6 +259,34 @@ public async Task> GetPaymentsByDateRangeAsync(DateTime startDate, } } + /// + /// Gets payments with all related entities loaded. + /// + public async Task> GetPaymentsWithRelationsAsync() + { + try + { + var organizationId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _context.Payments + .Include(p => p.Invoice) + .ThenInclude(i => i.Lease) + .ThenInclude(l => l.Property) + .Include(p => p.Invoice) + .ThenInclude(i => i.Lease) + .ThenInclude(l => l.Tenant) + .Include(p => p.Document) + .Where(p => !p.IsDeleted + && p.OrganizationId == organizationId) + .ToListAsync(); + } + catch (Exception ex) + { + await HandleExceptionAsync(ex, "GetPaymentsWithRelations"); + throw; + } + } + /// /// Calculates the total payments received within a date range. /// @@ -339,6 +374,32 @@ public async Task GetTotalPaidForInvoiceAsync(Guid invoiceId) } } + /// + /// Generates a unique payment number in the format PYMT-YYYYMMDD-####. + /// + public async Task GeneratePaymentNumberAsync() + { + try + { + var organizationId = await _userContext.GetActiveOrganizationIdAsync(); + var today = DateTime.Now.Date; + + // Get count of payments for today to generate sequential number + var todayPaymentCount = await _context.Payments + .Where(p => p.OrganizationId == organizationId + && p.PaidOn.Date == today) + .CountAsync(); + + var nextNumber = todayPaymentCount + 1; + return $"PYMT-{DateTime.Now:yyyyMMdd}-{nextNumber:D4}"; + } + catch (Exception ex) + { + await HandleExceptionAsync(ex, "GeneratePaymentNumber"); + throw; + } + } + /// /// Updates the invoice status and paid amount after a payment change. /// @@ -359,39 +420,45 @@ private async Task UpdateInvoiceAfterPaymentChangeAsync(Guid invoiceId) invoice.AmountPaid = totalPaid; - var totalDue = invoice.Amount + (invoice.LateFeeAmount ?? 0); + // Total due is the invoice amount (which includes late fees already added by ScheduledTaskService) + var totalDue = invoice.Amount; // Update invoice status based on payment - if (totalPaid >= totalDue) - { - invoice.Status = ApplicationConstants.InvoiceStatuses.Paid; - invoice.PaidOn = invoice.Payments - .Where(p => !p.IsDeleted) - .OrderByDescending(p => p.PaidOn) - .FirstOrDefault()?.PaidOn ?? DateTime.UtcNow; - } - else if (totalPaid > 0 && invoice.Status != ApplicationConstants.InvoiceStatuses.Cancelled) + // Don't change status if invoice is Cancelled or Voided + if (invoice.Status != ApplicationConstants.InvoiceStatuses.Cancelled + && invoice.Status != ApplicationConstants.InvoiceStatuses.Voided) { - // Invoice is partially paid - if (invoice.DueOn < DateTime.Today) + if (totalPaid >= totalDue) { - invoice.Status = ApplicationConstants.InvoiceStatuses.Overdue; + invoice.Status = ApplicationConstants.InvoiceStatuses.Paid; + invoice.PaidOn = invoice.Payments + .Where(p => !p.IsDeleted) + .OrderByDescending(p => p.PaidOn) + .FirstOrDefault()?.PaidOn ?? DateTime.UtcNow; } - else - { - invoice.Status = ApplicationConstants.InvoiceStatuses.Pending; - } - } - else if (invoice.Status != ApplicationConstants.InvoiceStatuses.Cancelled) - { - // No payments - if (invoice.DueOn < DateTime.Today) + else if (totalPaid > 0) { - invoice.Status = ApplicationConstants.InvoiceStatuses.Overdue; + // Invoice is partially paid + if (invoice.DueOn < DateTime.Today) + { + invoice.Status = ApplicationConstants.InvoiceStatuses.Overdue; + } + else + { + invoice.Status = ApplicationConstants.InvoiceStatuses.PaidPartial; + } } else { - invoice.Status = ApplicationConstants.InvoiceStatuses.Pending; + // No payments + if (invoice.DueOn < DateTime.Today) + { + invoice.Status = ApplicationConstants.InvoiceStatuses.Overdue; + } + else + { + invoice.Status = ApplicationConstants.InvoiceStatuses.Pending; + } } } diff --git a/2-Aquiis.Application/Services/PropertyService.cs b/2-Aquiis.Application/Services/PropertyService.cs index 3cbabc5..aa29d2f 100644 --- a/2-Aquiis.Application/Services/PropertyService.cs +++ b/2-Aquiis.Application/Services/PropertyService.cs @@ -69,6 +69,8 @@ public override async Task CreateAsync(Property property) return await _context.Properties .Include(p => p.Leases) .Include(p => p.Documents) + .Include(p => p.Repairs) + .Include(p => p.MaintenanceRequests) .FirstOrDefaultAsync(p => p.Id == propertyId && p.OrganizationId == organizationId && !p.IsDeleted); @@ -98,6 +100,8 @@ public async Task> GetPropertiesWithRelationsAsync() return await _context.Properties .Include(p => p.Leases) .Include(p => p.Documents) + .Include(p => p.Repairs) + .Include(p => p.MaintenanceRequests) .Where(p => !p.IsDeleted && p.OrganizationId == organizationId) .ToListAsync(); } @@ -234,7 +238,7 @@ public async Task CalculateOccupancyRateAsync() var organizationId = await _userContext.GetActiveOrganizationIdAsync(); var totalProperties = await _context.Properties - .CountAsync(p => !p.IsDeleted && p.IsAvailable && p.OrganizationId == organizationId); + .CountAsync(p => !p.IsDeleted && p.OrganizationId == organizationId); if (totalProperties == 0) { @@ -243,7 +247,6 @@ public async Task CalculateOccupancyRateAsync() var occupiedProperties = await _context.Properties .CountAsync(p => !p.IsDeleted && - p.IsAvailable && p.OrganizationId == organizationId && _context.Leases.Any(l => l.PropertyId == p.Id && @@ -259,6 +262,164 @@ public async Task CalculateOccupancyRateAsync() } } + /// + /// Calculates the annual occupancy rate for a single property based on days occupied. + /// Default period starts April 1 of current year (fiscal year). + /// + /// Property ID to calculate occupancy for + /// Start date of annual period (defaults to April 1 of current year) + /// Occupancy rate as percentage (0-100) + public async Task CalculatePropertyOccupancyRateAsync(Guid propertyId, DateTime? periodStart = null) + { + try + { + var organizationId = await _userContext.GetActiveOrganizationIdAsync(); + + // Default to April 1 of current year if not specified + var startDate = periodStart ?? new DateTime(DateTime.Today.Year, 4, 1); + var endDate = startDate.AddYears(1).AddDays(-1); + + // Get all leases for this property that overlap with the period + // Include all occupied statuses: Active, Renewed, Month-to-Month, Notice Given, Terminated + var leases = await _context.Leases + .Where(l => l.PropertyId == propertyId && + l.OrganizationId == organizationId && + !l.IsDeleted && + (l.Status == ApplicationConstants.LeaseStatuses.Active || + l.Status == ApplicationConstants.LeaseStatuses.Renewed || + l.Status == ApplicationConstants.LeaseStatuses.MonthToMonth || + l.Status == ApplicationConstants.LeaseStatuses.NoticeGiven || + l.Status == ApplicationConstants.LeaseStatuses.Terminated) && + l.StartDate <= endDate) + .ToListAsync(); + + // Calculate days occupied within the period + var daysOccupied = 0; + foreach (var lease in leases) + { + // For terminated leases, use ActualMoveOutDate; otherwise use EndDate + var effectiveEndDate = lease.Status == ApplicationConstants.LeaseStatuses.Terminated && lease.ActualMoveOutDate.HasValue + ? lease.ActualMoveOutDate.Value + : lease.EndDate; + + // Only count if lease overlaps with report period + if (effectiveEndDate >= startDate) + { + var leaseStart = lease.StartDate < startDate ? startDate : lease.StartDate; + var leaseEnd = effectiveEndDate > endDate ? endDate : effectiveEndDate; + + if (leaseEnd >= leaseStart) + { + daysOccupied += (leaseEnd - leaseStart).Days + 1; // +1 to include both start and end dates + } + } + } + + // Calculate total days in period + var totalDays = (endDate - startDate).Days + 1; + + // Return occupancy rate as percentage + return totalDays > 0 ? (decimal)daysOccupied / totalDays * 100 : 0; + } + catch (Exception ex) + { + await HandleExceptionAsync(ex, "CalculatePropertyOccupancyRate"); + throw; + } + } + + /// + /// Calculates the annual occupancy rate for the entire portfolio. + /// Average of all properties' occupancy rates weighted by number of properties. + /// Default period starts April 1 of current year (fiscal year). + /// + /// Start date of annual period (defaults to April 1 of current year) + /// Portfolio occupancy rate as percentage (0-100) + public async Task CalculatePortfolioOccupancyRateAsync(DateTime? periodStart = null) + { + try + { + var organizationId = await _userContext.GetActiveOrganizationIdAsync(); + + // Get all properties for the organization + var properties = await _context.Properties + .Where(p => !p.IsDeleted && p.OrganizationId == organizationId) + .Select(p => p.Id) + .ToListAsync(); + + if (properties.Count == 0) + { + return 0; + } + + // Calculate total occupied days and total available days across all properties + // Default to current fiscal year (April 1 - March 31) + // If today is Jan-Mar, use April 1 of previous year + // If today is Apr-Dec, use April 1 of current year + DateTime startDate; + if (periodStart.HasValue) + { + startDate = periodStart.Value; + } + else + { + var today = DateTime.Today; + startDate = today.Month < 4 + ? new DateTime(today.Year - 1, 4, 1) + : new DateTime(today.Year, 4, 1); + } + var endDate = startDate.AddYears(1).AddDays(-1); + var totalDays = (endDate - startDate).Days + 1; + + var totalDaysOccupied = 0; + var totalDaysAvailable = properties.Count * totalDays; + + // For each property, calculate days occupied + foreach (var propertyId in properties) + { + var leases = await _context.Leases + .Where(l => l.PropertyId == propertyId && + l.OrganizationId == organizationId && + !l.IsDeleted && + (l.Status == ApplicationConstants.LeaseStatuses.Active || + l.Status == ApplicationConstants.LeaseStatuses.Renewed || + l.Status == ApplicationConstants.LeaseStatuses.MonthToMonth || + l.Status == ApplicationConstants.LeaseStatuses.NoticeGiven || + l.Status == ApplicationConstants.LeaseStatuses.Terminated) && + l.StartDate <= endDate) + .ToListAsync(); + + foreach (var lease in leases) + { + // For terminated leases, use ActualMoveOutDate; otherwise use EndDate + var effectiveEndDate = lease.Status == ApplicationConstants.LeaseStatuses.Terminated && lease.ActualMoveOutDate.HasValue + ? lease.ActualMoveOutDate.Value + : lease.EndDate; + + // Only count if lease overlaps with report period + if (effectiveEndDate >= startDate) + { + var leaseStart = lease.StartDate < startDate ? startDate : lease.StartDate; + var leaseEnd = effectiveEndDate > endDate ? endDate : effectiveEndDate; + + if (leaseEnd >= leaseStart) + { + totalDaysOccupied += (leaseEnd - leaseStart).Days + 1; + } + } + } + } + + // Return portfolio occupancy rate + return totalDaysAvailable > 0 ? (decimal)totalDaysOccupied / totalDaysAvailable * 100 : 0; + } + catch (Exception ex) + { + await HandleExceptionAsync(ex, "CalculatePortfolioOccupancyRate"); + throw; + } + } + /// /// Retrieves properties that need routine inspection. /// diff --git a/2-Aquiis.Application/Services/RepairService.cs b/2-Aquiis.Application/Services/RepairService.cs new file mode 100644 index 0000000..1d96373 --- /dev/null +++ b/2-Aquiis.Application/Services/RepairService.cs @@ -0,0 +1,346 @@ +using Aquiis.Core.Constants; +using Aquiis.Core.Entities; +using Aquiis.Core.Interfaces.Services; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +namespace Aquiis.Application.Services; + +/// +/// Service for managing repairs (work performed on properties WITHOUT workflow/status tracking). +/// Repairs can be standalone or part of a MaintenanceRequest composition. +/// +public class RepairService : BaseService +{ + public RepairService( + ApplicationDbContext context, + ILogger logger, + IUserContextService userContext, + IOptions settings) + : base(context, logger, userContext, settings) + { + } + + /// + /// Validates repair business rules before create/update. + /// + protected override async Task ValidateEntityAsync(Repair entity) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + // Validate PropertyId exists and belongs to active organization + var propertyExists = await _context.Properties + .AnyAsync(p => p.Id == entity.PropertyId && p.OrganizationId == orgId && !p.IsDeleted); + + if (!propertyExists) + { + throw new InvalidOperationException("Property not found or does not belong to your organization."); + } + + // Validate MaintenanceRequestId if provided + if (entity.MaintenanceRequestId.HasValue) + { + var maintenanceRequest = await _context.MaintenanceRequests + .Include(mr => mr.Property) + .FirstOrDefaultAsync(mr => mr.Id == entity.MaintenanceRequestId.Value && !mr.IsDeleted); + + if (maintenanceRequest == null) + { + throw new InvalidOperationException("Maintenance request not found."); + } + + if (maintenanceRequest.Property?.OrganizationId != orgId) + { + throw new InvalidOperationException("Maintenance request does not belong to your organization."); + } + + // Ensure repair belongs to same property as maintenance request + if (maintenanceRequest.PropertyId != entity.PropertyId) + { + throw new InvalidOperationException("Repair must belong to the same property as the maintenance request."); + } + } + + // Validate LeaseId if provided + if (entity.LeaseId.HasValue) + { + var lease = await _context.Leases + .Include(l => l.Property) + .FirstOrDefaultAsync(l => l.Id == entity.LeaseId.Value && !l.IsDeleted); + + if (lease == null) + { + throw new InvalidOperationException("Lease not found."); + } + + if (lease.Property?.OrganizationId != orgId) + { + throw new InvalidOperationException("Lease does not belong to your organization."); + } + + // Ensure repair belongs to same property as lease + if (lease.PropertyId != entity.PropertyId) + { + throw new InvalidOperationException("Repair must belong to the same property as the lease."); + } + } + + // Validate CompletedOn not in future + if (entity.CompletedOn.HasValue && entity.CompletedOn.Value > DateTime.UtcNow) + { + throw new InvalidOperationException("Completion date cannot be in the future."); + } + + // Validate Cost is non-negative + if (entity.Cost < 0) + { + throw new InvalidOperationException("Cost cannot be negative."); + } + + // Validate DurationMinutes is non-negative + if (entity.DurationMinutes < 0) + { + throw new InvalidOperationException("Duration cannot be negative."); + } + + // Validate warranty dates + if (entity.WarrantyApplies && entity.WarrantyExpiresOn.HasValue) + { + if (!entity.CompletedOn.HasValue) + { + throw new InvalidOperationException("Warranty expiration date requires a completion date."); + } + + if (entity.WarrantyExpiresOn.Value <= entity.CompletedOn.Value) + { + throw new InvalidOperationException("Warranty expiration date must be after completion date."); + } + } + + await base.ValidateEntityAsync(entity); + } + + /// + /// Gets all repairs for the active organization with Property navigation included. + /// Overrides base method to include navigation properties. + /// + public override async Task> GetAllAsync() + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => !r.IsDeleted && r.OrganizationId == orgId) + .Include(r => r.Property) + .OrderByDescending(r => r.CompletedOn ?? r.CreatedOn) + .ToListAsync(); + } + + /// + /// Gets all repairs for a specific property. + /// + public async Task> GetRepairsByPropertyAsync(Guid propertyId) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => r.PropertyId == propertyId && !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.MaintenanceRequest) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderByDescending(r => r.CompletedOn ?? r.CreatedOn) + .ToListAsync(); + } + + /// + /// Gets all repairs that are part of a specific maintenance request. + /// + public async Task> GetRepairsByMaintenanceRequestAsync(Guid maintenanceRequestId) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => r.MaintenanceRequestId == maintenanceRequestId && !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.MaintenanceRequest) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderByDescending(r => r.CompletedOn ?? r.CreatedOn) + .ToListAsync(); + } + + /// + /// Gets all standalone repairs (not associated with any maintenance request). + /// These are repairs logged directly without workflow. + /// + public async Task> GetStandaloneRepairsAsync() + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => r.MaintenanceRequestId == null && !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderByDescending(r => r.CompletedOn ?? r.CreatedOn) + .ToListAsync(); + } + + /// + /// Gets all repairs completed within a date range. + /// + public async Task> GetRepairsByDateRangeAsync(DateTime startDate, DateTime endDate) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => r.CompletedOn.HasValue && + r.CompletedOn.Value >= startDate && + r.CompletedOn.Value <= endDate && + !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.MaintenanceRequest) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderByDescending(r => r.CompletedOn) + .ToListAsync(); + } + + /// + /// Gets repairs in progress (CompletedOn is null). + /// + public async Task> GetRepairsInProgressAsync() + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + return await _dbSet + .Where(r => !r.CompletedOn.HasValue && !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.MaintenanceRequest) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderByDescending(r => r.CreatedOn) + .ToListAsync(); + } + + /// + /// Gets repair cost summary by property, optionally filtered by date range. + /// + public async Task> GetRepairCostsByPropertyAsync(DateTime? startDate = null, DateTime? endDate = null) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + var query = _dbSet + .Where(r => !r.IsDeleted) + .Include(r => r.Property) + .Where(r => r.Property!.OrganizationId == orgId); + + if (startDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value >= startDate.Value); + } + + if (endDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value <= endDate.Value); + } + + return await query + .GroupBy(r => r.PropertyId) + .Select(g => new { PropertyId = g.Key, TotalCost = g.Sum(r => r.Cost) }) + .ToDictionaryAsync(x => x.PropertyId, x => x.TotalCost); + } + + /// + /// Gets all repairs currently under warranty. + /// + public async Task> GetRepairsUnderWarrantyAsync() + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + var today = DateTime.UtcNow; + + return await _dbSet + .Where(r => r.WarrantyApplies && + r.WarrantyExpiresOn.HasValue && + r.WarrantyExpiresOn.Value >= today && + !r.IsDeleted) + .Include(r => r.Property) + .Include(r => r.MaintenanceRequest) + .Include(r => r.Lease) + .Where(r => r.Property!.OrganizationId == orgId) + .OrderBy(r => r.WarrantyExpiresOn) + .ToListAsync(); + } + + /// + /// Gets repairs by type for reporting/analytics. + /// + public async Task> GetRepairCountsByTypeAsync(DateTime? startDate = null, DateTime? endDate = null) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + var query = _dbSet + .Where(r => !r.IsDeleted) + .Include(r => r.Property) + .Where(r => r.Property!.OrganizationId == orgId); + + if (startDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value >= startDate.Value); + } + + if (endDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value <= endDate.Value); + } + + return await query + .GroupBy(r => r.RepairType) + .Select(g => new { RepairType = g.Key, Count = g.Count() }) + .ToDictionaryAsync(x => x.RepairType, x => x.Count); + } + + /// + /// Gets total repair costs for the organization within a date range. + /// + public async Task GetTotalRepairCostsAsync(DateTime? startDate = null, DateTime? endDate = null) + { + var orgId = await _userContext.GetActiveOrganizationIdAsync(); + + var query = _dbSet + .Where(r => !r.IsDeleted) + .Include(r => r.Property) + .Where(r => r.Property!.OrganizationId == orgId); + + if (startDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value >= startDate.Value); + } + + if (endDate.HasValue) + { + query = query.Where(r => r.CompletedOn.HasValue && r.CompletedOn.Value <= endDate.Value); + } + + return await query.SumAsync(r => r.Cost); + } + + /// + /// Marks a repair as completed (sets CompletedOn to current timestamp). + /// + public async Task CompleteRepairAsync(Guid repairId) + { + var repair = await GetByIdAsync(repairId); + if (repair == null) return null; + + if (repair.CompletedOn.HasValue) + { + throw new InvalidOperationException("Repair is already marked as completed."); + } + + repair.CompletedOn = DateTime.UtcNow; + await UpdateAsync(repair); + return repair; + } +} diff --git a/2-Aquiis.Application/Services/SchemaValidationService.cs b/2-Aquiis.Application/Services/SchemaValidationService.cs index 49e2b32..7762c14 100644 --- a/2-Aquiis.Application/Services/SchemaValidationService.cs +++ b/2-Aquiis.Application/Services/SchemaValidationService.cs @@ -52,7 +52,7 @@ public SchemaValidationService( dbVersion); } - _logger.LogInformation("Schema version validated successfully: {Version}", dbVersion); + _logger.LogDebug("Schema version validated successfully: {Version}", dbVersion); return (true, $"Schema version {dbVersion} is valid", dbVersion); } catch (Exception ex) diff --git a/2-Aquiis.Application/Services/SimpleStartFinancialReportService.cs b/2-Aquiis.Application/Services/SimpleStartFinancialReportService.cs new file mode 100644 index 0000000..99cf7c3 --- /dev/null +++ b/2-Aquiis.Application/Services/SimpleStartFinancialReportService.cs @@ -0,0 +1,307 @@ +using Aquiis.Application.Services; +using Aquiis.Core.Constants; +using Aquiis.Core.Entities; +using Aquiis.Infrastructure.Data; +using Microsoft.EntityFrameworkCore; + +namespace Aquiis.Application.Services; + +/// +/// SimpleStart-specific financial report service that uses Repairs for expenses +/// instead of MaintenanceRequests (which are used in Professional edition). +/// +public class SimpleStartFinancialReportService +{ + private readonly IDbContextFactory _contextFactory; + + public SimpleStartFinancialReportService(IDbContextFactory contextFactory) + { + _contextFactory = contextFactory; + } + + /// + /// Generate income statement for a specific period and optional property. + /// Uses Repairs for expense tracking (SimpleStart approach). + /// + public async Task GenerateIncomeStatementAsync( + Guid organizationId, + DateTime startDate, + DateTime endDate, + Guid? propertyId = null) + { + using var context = await _contextFactory.CreateDbContextAsync(); + + var statement = new IncomeStatement + { + StartDate = startDate, + EndDate = endDate, + PropertyId = propertyId + }; + + // Get property name if filtering by property + if (propertyId.HasValue) + { + var property = await context.Properties + .Where(p => p.Id == propertyId.Value && p.OrganizationId == organizationId) + .FirstOrDefaultAsync(); + statement.PropertyName = property?.Address; + } + + // Calculate total rent income from payments (all payments are rent payments) + var paymentsQuery = context.Payments + .Include(p => p.Invoice) + .ThenInclude(i => i.Lease) + .Where(p => p.Invoice.Lease.Property.OrganizationId == organizationId && + p.PaidOn >= startDate && + p.PaidOn <= endDate); + + if (propertyId.HasValue) + { + paymentsQuery = paymentsQuery.Where(p => p.Invoice.Lease.PropertyId == propertyId.Value); + } + + var totalPayments = await paymentsQuery.SumAsync(p => p.Amount); + statement.TotalRentIncome = totalPayments; + statement.TotalOtherIncome = 0; // No other income tracked currently + + // Get repair expenses (SimpleStart uses Repairs instead of MaintenanceRequests) + var repairsQuery = context.Repairs + .Where(r => !r.IsDeleted && + r.OrganizationId == organizationId && + r.CompletedOn.HasValue && + r.CompletedOn.Value >= startDate && + r.CompletedOn.Value <= endDate && + r.Cost > 0); + + if (propertyId.HasValue) + { + repairsQuery = repairsQuery.Where(r => r.PropertyId == propertyId.Value); + } + + var repairs = await repairsQuery.ToListAsync(); + + // All repair costs go to MaintenanceExpenses + statement.MaintenanceExpenses = repairs.Sum(r => r.Cost); + + // Other expense categories are currently zero (no data tracked for these yet) + statement.UtilityExpenses = 0; + statement.InsuranceExpenses = 0; + statement.TaxExpenses = 0; + statement.ManagementFees = 0; + statement.OtherExpenses = 0; + + return statement; + } + + /// + /// Generate property performance comparison report. + /// Uses Repairs for expense tracking (SimpleStart approach). + /// + public async Task> GeneratePropertyPerformanceAsync( + Guid organizationId, + DateTime startDate, + DateTime endDate) + { + using var context = await _contextFactory.CreateDbContextAsync(); + + var properties = await context.Properties + .Where(p => p.OrganizationId == organizationId) + .ToListAsync(); + + var performance = new List(); + var totalDays = (endDate - startDate).Days + 1; + + foreach (var property in properties) + { + // Calculate income from rent payments + var income = await context.Payments + .Include(p => p.Invoice) + .ThenInclude(i => i.Lease) + .Where(p => p.Invoice.Lease.PropertyId == property.Id && + p.PaidOn >= startDate && + p.PaidOn <= endDate) + .SumAsync(p => p.Amount); + + // Calculate expenses from repairs (SimpleStart approach) + var expenses = await context.Repairs + .Where(r => !r.IsDeleted && + r.PropertyId == property.Id && + r.OrganizationId == organizationId && + r.CompletedOn.HasValue && + r.CompletedOn.Value >= startDate && + r.CompletedOn.Value <= endDate && + r.Cost > 0) + .SumAsync(r => r.Cost); + + // Calculate occupancy days + // Include occupied lease statuses: Active, Renewed, Month-to-Month, Notice Given + // Also include Terminated to count actual days occupied before move-out + var leases = await context.Leases + .Where(l => l.PropertyId == property.Id && + !l.IsDeleted && + (l.Status == ApplicationConstants.LeaseStatuses.Active || + l.Status == ApplicationConstants.LeaseStatuses.Renewed || + l.Status == ApplicationConstants.LeaseStatuses.MonthToMonth || + l.Status == ApplicationConstants.LeaseStatuses.NoticeGiven || + l.Status == ApplicationConstants.LeaseStatuses.Terminated) && + l.StartDate <= endDate) + .ToListAsync(); + + var occupancyDays = 0; + foreach (var lease in leases) + { + // For terminated leases, use ActualMoveOutDate; otherwise use EndDate + var effectiveEndDate = lease.Status == ApplicationConstants.LeaseStatuses.Terminated && lease.ActualMoveOutDate.HasValue + ? lease.ActualMoveOutDate.Value + : lease.EndDate; + + // Only count if lease overlaps with report period + if (effectiveEndDate >= startDate) + { + var leaseStart = lease.StartDate > startDate ? lease.StartDate : startDate; + var leaseEnd = effectiveEndDate < endDate ? effectiveEndDate : endDate; + + if (leaseEnd >= leaseStart) + { + occupancyDays += (leaseEnd - leaseStart).Days + 1; + } + } + } + + // Calculate ROI (simplified - based on profit margin since we don't track purchase price) + var roi = income > 0 + ? ((income - expenses) / income) * 100 + : 0; + + performance.Add(new PropertyPerformance + { + PropertyId = property.Id, + PropertyName = property.Address, + PropertyAddress = property.Address, + TotalIncome = income, + TotalExpenses = expenses, + ROI = roi, + OccupancyDays = occupancyDays, + TotalDays = totalDays + }); + } + + return performance.OrderByDescending(p => p.NetIncome).ToList(); + } + + /// + /// Generate tax report data for Schedule E. + /// Uses Repairs for expense tracking (SimpleStart approach). + /// + public async Task> GenerateTaxReportAsync(Guid organizationId, int year, Guid? propertyId = null) + { + using var context = await _contextFactory.CreateDbContextAsync(); + var startDate = new DateTime(year, 1, 1); + var endDate = new DateTime(year, 12, 31); + + var propertiesQuery = context.Properties.Where(p => p.OrganizationId == organizationId); + if (propertyId.HasValue) + { + propertiesQuery = propertiesQuery.Where(p => p.Id == propertyId.Value); + } + + var properties = await propertiesQuery.ToListAsync(); + var taxReports = new List(); + + foreach (var property in properties) + { + // Calculate rent income from payments + var rentIncome = await context.Payments + .Include(p => p.Invoice) + .ThenInclude(i => i.Lease) + .Where(p => p.Invoice.Lease.PropertyId == property.Id && + p.PaidOn >= startDate && + p.PaidOn <= endDate) + .SumAsync(p => p.Amount); + + // Get repair expenses (SimpleStart approach) + var repairExpenses = await context.Repairs + .Where(r => !r.IsDeleted && + r.PropertyId == property.Id && + r.OrganizationId == organizationId && + r.CompletedOn.HasValue && + r.CompletedOn.Value >= startDate && + r.CompletedOn.Value <= endDate && + r.Cost > 0) + .ToListAsync(); + + // Calculate depreciation (simplified - 27.5 years for residential rental) + // Note: Since we don't track purchase price, this should be manually entered + var depreciationAmount = 0m; + + var totalRepairCost = repairExpenses.Sum(r => r.Cost); + + var taxReport = new TaxReportData + { + Year = year, + PropertyId = property.Id, + PropertyName = property.Address, + TotalRentIncome = rentIncome, + DepreciationAmount = depreciationAmount, + + // Currently only repairs are tracked + Advertising = 0, + Cleaning = 0, + Insurance = 0, + Legal = 0, + Management = 0, + MortgageInterest = 0, + Repairs = totalRepairCost, // All repair costs + Supplies = 0, + Taxes = 0, + Utilities = 0, + Other = 0 + }; + + taxReport.TotalExpenses = totalRepairCost; + + taxReports.Add(taxReport); + } + + return taxReports; + } + + /// + /// Generate rent roll report showing all properties and tenants. + /// This method is the same as base FinancialReportService since it doesn't involve expenses. + /// + public async Task> GenerateRentRollAsync(Guid organizationId, DateTime asOfDate) + { + using var context = await _contextFactory.CreateDbContextAsync(); + + var rentRoll = await context.Leases + .Include(l => l.Property) + .Include(l => l.Tenant) + .Include(l => l.Invoices) + .ThenInclude(i => i.Payments) + .Where(l => l.Property.OrganizationId == organizationId && + l.Tenant != null && + l.StartDate <= asOfDate && + l.EndDate >= asOfDate) + .OrderBy(l => l.Property.Address) + .ThenBy(l => l.Tenant!.LastName) + .Select(l => new RentRollItem + { + PropertyId = l.PropertyId, + PropertyName = l.Property.Address, + PropertyAddress = l.Property.Address, + TenantId = l.TenantId, + TenantName = $"{l.Tenant!.FirstName} {l.Tenant!.LastName}", + LeaseStatus = l.Status, + LeaseStartDate = l.StartDate, + LeaseEndDate = l.EndDate, + MonthlyRent = l.MonthlyRent, + SecurityDeposit = l.SecurityDeposit, + TotalPaid = l.Invoices.SelectMany(i => i.Payments).Sum(p => p.Amount), + TotalDue = l.Invoices.Where(i => i.Status != "Cancelled").Sum(i => i.Amount) + }) + .ToListAsync(); + + return rentRoll; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Common/EntityFilterBar.razor b/3-Aquiis.UI.Shared/Components/Common/EntityFilterBar.razor new file mode 100644 index 0000000..bf979ed --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Common/EntityFilterBar.razor @@ -0,0 +1,164 @@ +@namespace Aquiis.UI.Shared.Components.Common +@typeparam TStatus +@typeparam TPriority +@typeparam TType + +
+ @* Search Box *@ + @if (ShowSearch) + { +
+
+ + +
+
+ } + + @* Status Filter *@ + @if (ShowStatusFilter && StatusOptions.Any()) + { +
+ +
+ } + + @* Priority Filter *@ + @if (ShowPriorityFilter && PriorityOptions.Any()) + { +
+ +
+ } + + @* Type Filter *@ + @if (ShowTypeFilter && TypeOptions.Any()) + { +
+ +
+ } + + @* Custom Secondary Filter *@ + @if (SecondaryFilter != null) + { +
+ @SecondaryFilter +
+ } + + @* Group Toggle *@ + @if (ShowGroupToggle && GroupedDataAvailable) + { +
+
+ + +
+
+ } + + @* Clear Filters Button *@ + @if (ShowClearButton) + { +
+ +
+ } +
+ +@code { + // Search parameters + [Parameter] public bool ShowSearch { get; set; } = true; + [Parameter] public string SearchPlaceholder { get; set; } = "Search..."; + [Parameter] public string SearchTerm { get; set; } = string.Empty; + [Parameter] public EventCallback OnSearchChanged { get; set; } + + // Status filter parameters + [Parameter] public bool ShowStatusFilter { get; set; } = true; + [Parameter] public string StatusLabel { get; set; } = "All Statuses"; + [Parameter] public string StatusFilter { get; set; } = string.Empty; + [Parameter] public List StatusOptions { get; set; } = new(); + [Parameter] public EventCallback OnStatusChanged { get; set; } + + // Priority filter parameters + [Parameter] public bool ShowPriorityFilter { get; set; } = false; + [Parameter] public string PriorityLabel { get; set; } = "All Priorities"; + [Parameter] public string PriorityFilter { get; set; } = string.Empty; + [Parameter] public List PriorityOptions { get; set; } = new(); + [Parameter] public EventCallback OnPriorityChanged { get; set; } + + // Type filter parameters + [Parameter] public bool ShowTypeFilter { get; set; } = false; + [Parameter] public string TypeLabel { get; set; } = "All Types"; + [Parameter] public string TypeFilter { get; set; } = string.Empty; + [Parameter] public List TypeOptions { get; set; } = new(); + [Parameter] public EventCallback OnTypeChanged { get; set; } + + // Custom secondary filter + [Parameter] public RenderFragment? SecondaryFilter { get; set; } + + // Group toggle parameters + [Parameter] public bool ShowGroupToggle { get; set; } = false; + [Parameter] public bool GroupedDataAvailable { get; set; } + [Parameter] public string GroupLabel { get; set; } = "Group by Property"; + [Parameter] public bool GroupByProperty { get; set; } + [Parameter] public EventCallback OnGroupToggled { get; set; } + + // Clear button parameters + [Parameter] public bool ShowClearButton { get; set; } = false; + [Parameter] public EventCallback OnClearFilters { get; set; } + + // Generate unique ID for the toggle to avoid label conflicts + private string GroupToggleId => $"groupToggle_{Guid.NewGuid():N}"; + + private async Task HandleSearchInput(ChangeEventArgs e) + { + await OnSearchChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleStatusChange(ChangeEventArgs e) + { + await OnStatusChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandlePriorityChange(ChangeEventArgs e) + { + await OnPriorityChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleTypeChange(ChangeEventArgs e) + { + await OnTypeChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleGroupToggle(ChangeEventArgs e) + { + await OnGroupToggled.InvokeAsync(e.Value is bool boolValue && boolValue); + } +} diff --git a/3-Aquiis.UI.Shared/Components/Common/MetricsCard.razor b/3-Aquiis.UI.Shared/Components/Common/MetricsCard.razor new file mode 100644 index 0000000..301a165 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Common/MetricsCard.razor @@ -0,0 +1,32 @@ +
+
+
+
+
+

@Count

+

@Title

+
+
+ +
+
+
+
+
+@code { + [Parameter] + public RenderFragment? ChildContent { get; set; } + + [Parameter] + public string Title { get; set; } = string.Empty; + + [Parameter] + public string Count { get; set; } = string.Empty; + + [Parameter] + public string? IconCssClass { get; set; } + + [Parameter] + public string? ColorClass { get; set; } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Common/TrimmedInputText.razor b/3-Aquiis.UI.Shared/Components/Common/TrimmedInputText.razor new file mode 100644 index 0000000..b83584d --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Common/TrimmedInputText.razor @@ -0,0 +1,31 @@ +@inherits InputText + +@* + A text input component that automatically trims leading and trailing whitespace + on blur (when user leaves the field). Extends standard InputText functionality. + + Usage: + +*@ + + + +@code { + private void HandleInput(ChangeEventArgs e) + { + CurrentValueAsString = e.Value?.ToString(); + } + + private void HandleBlur(FocusEventArgs e) + { + // Trim the value when user leaves the field + if (!string.IsNullOrEmpty(CurrentValueAsString)) + { + CurrentValueAsString = CurrentValueAsString.Trim(); + } + } +} diff --git a/3-Aquiis.UI.Shared/Components/Common/UserAvatar.razor b/3-Aquiis.UI.Shared/Components/Common/UserAvatar.razor new file mode 100644 index 0000000..6bfa197 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Common/UserAvatar.razor @@ -0,0 +1,40 @@ + +
+ @if (!string.IsNullOrWhiteSpace(FirstName) || !string.IsNullOrWhiteSpace(LastName)) + { + @GetInitials() + } + else + { + + } +
+ +@code { + [Parameter, EditorRequired] + public int Size { get; set; } = 48; + + [Parameter , EditorRequired] + public string FirstName { get; set; } = string.Empty; + + [Parameter , EditorRequired] + public string LastName { get; set; } = string.Empty; + + private string GetInitials() + { + var initials = string.Empty; + + if (!string.IsNullOrWhiteSpace(FirstName)) + { + initials += FirstName[0]; + } + + if (!string.IsNullOrWhiteSpace(LastName)) + { + initials += LastName[0]; + } + + return initials.ToUpper(); + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Documents/DocumentListView.razor b/3-Aquiis.UI.Shared/Components/Entities/Documents/DocumentListView.razor new file mode 100644 index 0000000..382dde5 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Documents/DocumentListView.razor @@ -0,0 +1,173 @@ +@using Aquiis.Core.Entities + +
+
+
+ Documents +
+ @if (ShowUploadButton && OnUploadDocument.HasDelegate) + { + + } +
+
+ @if (Documents == null) + { +
+
+ Loading... +
+
+ } + else if (!Documents.Any()) + { +

No documents uploaded for this property.

+ } + else + { + @if (ShowGroupByType && GroupedDocuments != null && GroupedDocuments.Any()) + { + @foreach (var group in GroupedDocuments) + { +
+
+ @group.Key (@group.Count()) +
+
+ @foreach (var document in group.OrderByDescending(d => d.CreatedOn)) + { +
+ @RenderDocumentItem(document) +
+ } +
+
+ } + } + else + { +
+ @foreach (var document in Documents.OrderByDescending(d => d.CreatedOn)) + { +
+ @RenderDocumentItem(document) +
+ } +
+ } + } +
+
+ +@code { + [Parameter] + public List? Documents { get; set; } + + [Parameter] + public bool ShowUploadButton { get; set; } = true; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public bool ShowGroupByType { get; set; } = false; + + [Parameter] + public EventCallback OnUploadDocument { get; set; } + + [Parameter] + public EventCallback OnViewDocument { get; set; } + + [Parameter] + public EventCallback OnDownloadDocument { get; set; } + + [Parameter] + public EventCallback OnDeleteDocument { get; set; } + + private IEnumerable>? GroupedDocuments => + Documents?.GroupBy(d => d.DocumentType ?? "Other"); + + private RenderFragment RenderDocumentItem(Document document) => __builder => + { +
+
+
+ + @if (OnViewDocument.HasDelegate) + { + + @document.FileName + + } + else + { + @document.FileName + } +
+
+ @if (!ShowGroupByType && !string.IsNullOrEmpty(document.DocumentType)) + { + @document.DocumentType + } + + @FormatFileSize(document.FileSize) + • Uploaded @document.CreatedOn.ToString("MMM dd, yyyy") + +
+ @if (!string.IsNullOrEmpty(document.Description)) + { + @document.Description + } +
+
+ @if (OnViewDocument.HasDelegate) + { + + } + @if (OnDownloadDocument.HasDelegate) + { + + } + @if (OnDeleteDocument.HasDelegate) + { + + } +
+
+ }; + + private string GetFileIcon(string fileName) + { + var extension = Path.GetExtension(fileName)?.ToLower(); + return extension switch + { + ".pdf" => "bi-file-pdf text-danger", + ".doc" or ".docx" => "bi-file-word text-primary", + ".xls" or ".xlsx" => "bi-file-excel text-success", + ".jpg" or ".jpeg" or ".png" or ".gif" => "bi-file-image text-info", + ".zip" or ".rar" => "bi-file-zip text-warning", + _ => "bi-file-earmark" + }; + } + + private string FormatFileSize(long bytes) + { + string[] sizes = { "B", "KB", "MB", "GB" }; + double len = bytes; + int order = 0; + while (len >= 1024 && order < sizes.Length - 1) + { + order++; + len = len / 1024; + } + return $"{len:0.##} {sizes[order]}"; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionChecklistItem.razor b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionChecklistItem.razor new file mode 100644 index 0000000..3cf8ddf --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionChecklistItem.razor @@ -0,0 +1,51 @@ +
+
+ +
+
+
+ + +
+
+
+ +
+
+ +@code { + [Parameter] + public string Label { get; set; } = string.Empty; + + [Parameter] + public bool IsGood { get; set; } = true; + + [Parameter] + public EventCallback IsGoodChanged { get; set; } + + [Parameter] + public string? Notes { get; set; } + + [Parameter] + public EventCallback NotesChanged { get; set; } + + private async Task OnIsGoodChanged(ChangeEventArgs e) + { + IsGood = e.Value is bool b && b; + await IsGoodChanged.InvokeAsync(IsGood); + } + + private async Task OnNotesChanged(ChangeEventArgs e) + { + Notes = e.Value?.ToString(); + await NotesChanged.InvokeAsync(Notes); + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionModalView.razor b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionModalView.razor new file mode 100644 index 0000000..f7e6d8b --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionModalView.razor @@ -0,0 +1,134 @@ +@using Aquiis.Core.Entities + +
+
+ Inspection Date: +

@Inspection.CompletedOn.ToString("MMMM dd, yyyy")

+
+
+ Type: +

@Inspection.InspectionType

+
+
+ Overall Condition: +

@Inspection.OverallCondition

+
+
+ Inspected By: +

@(Inspection.InspectedBy ?? "Not specified")

+
+
+ +@if (Inspection.Lease != null) +{ +
+
+ Tenant: @Inspection.Lease.Tenant?.FullName +
+
+} + + + + + + + + + +@if (!string.IsNullOrEmpty(Inspection.GeneralNotes)) +{ +
+
+
General Notes
+
+
+

@Inspection.GeneralNotes

+
+
+} + +@if (!string.IsNullOrEmpty(Inspection.ActionItemsRequired)) +{ +
+ Action Items Required: +

@Inspection.ActionItemsRequired

+
+} + +@code { + [Parameter] + public Inspection Inspection { get; set; } = default!; + + private string GetConditionBadge(string condition) + { + return condition switch + { + "Excellent" => "bg-success", + "Good" => "bg-info", + "Fair" => "bg-warning", + "Poor" => "bg-danger", + _ => "bg-secondary" + }; + } + + private List<(string Label, bool IsGood, string? Notes)> GetExteriorItems(Inspection inspection) + { + return new List<(string Label, bool IsGood, string? Notes)> + { + ("Roof", inspection.ExteriorRoofGood, inspection.ExteriorRoofNotes), + ("Gutters & Downspouts", inspection.ExteriorGuttersGood, inspection.ExteriorGuttersNotes), + ("Siding/Exterior Walls", inspection.ExteriorSidingGood, inspection.ExteriorSidingNotes), + ("Windows (Exterior)", inspection.ExteriorWindowsGood, inspection.ExteriorWindowsNotes), + ("Doors (Exterior)", inspection.ExteriorDoorsGood, inspection.ExteriorDoorsNotes), + ("Foundation", inspection.ExteriorFoundationGood, inspection.ExteriorFoundationNotes), + ("Landscaping", inspection.LandscapingGood, inspection.LandscapingNotes) + }; + } + + private List<(string Label, bool IsGood, string? Notes)> GetInteriorItems(Inspection inspection) + { + return new List<(string Label, bool IsGood, string? Notes)> + { + ("Walls", inspection.InteriorWallsGood, inspection.InteriorWallsNotes), + ("Ceilings", inspection.InteriorCeilingsGood, inspection.InteriorCeilingsNotes), + ("Floors", inspection.InteriorFloorsGood, inspection.InteriorFloorsNotes), + ("Doors (Interior)", inspection.InteriorDoorsGood, inspection.InteriorDoorsNotes), + ("Windows (Interior)", inspection.InteriorWindowsGood, inspection.InteriorWindowsNotes) + }; + } + + private List<(string Label, bool IsGood, string? Notes)> GetKitchenItems(Inspection inspection) + { + return new List<(string Label, bool IsGood, string? Notes)> + { + ("Appliances", inspection.KitchenAppliancesGood, inspection.KitchenAppliancesNotes), + ("Cabinets", inspection.KitchenCabinetsGood, inspection.KitchenCabinetsNotes), + ("Countertops", inspection.KitchenCountersGood, inspection.KitchenCountersNotes), + ("Sink & Plumbing", inspection.KitchenSinkPlumbingGood, inspection.KitchenSinkPlumbingNotes) + }; + } + + private List<(string Label, bool IsGood, string? Notes)> GetBathroomItems(Inspection inspection) + { + return new List<(string Label, bool IsGood, string? Notes)> + { + ("Toilet", inspection.BathroomToiletGood, inspection.BathroomToiletNotes), + ("Sink & Vanity", inspection.BathroomSinkGood, inspection.BathroomSinkNotes), + ("Tub/Shower", inspection.BathroomTubShowerGood, inspection.BathroomTubShowerNotes), + ("Ventilation", inspection.BathroomVentilationGood, inspection.BathroomVentilationNotes) + }; + } + + private List<(string Label, bool IsGood, string? Notes)> GetSystemsItems(Inspection inspection) + { + return new List<(string Label, bool IsGood, string? Notes)> + { + ("HVAC System", inspection.HvacSystemGood, inspection.HvacSystemNotes), + ("Electrical System", inspection.ElectricalSystemGood, inspection.ElectricalSystemNotes), + ("Plumbing System", inspection.PlumbingSystemGood, inspection.PlumbingSystemNotes), + ("Smoke Detectors", inspection.SmokeDetectorsGood, inspection.SmokeDetectorsNotes), + ("Carbon Monoxide Detectors", inspection.CarbonMonoxideDetectorsGood, inspection.CarbonMonoxideDetectorsNotes) + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionSectionView.razor b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionSectionView.razor new file mode 100644 index 0000000..5fe9a2e --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Inspections/InspectionSectionView.razor @@ -0,0 +1,60 @@ +
+
+
@Title
+
+
+ @if (Items != null && Items.Any()) + { +
+ + + + + + + + + + @foreach (var item in Items) + { + + + + + + } + +
ItemStatusNotes
@item.Label + @if (item.IsGood) + { + Good + } + else + { + Issue + } + + @if (!string.IsNullOrEmpty(item.Notes)) + { + @item.Notes + } + else + { + - + } +
+
+ } +
+
+ +@code { + [Parameter] + public string Title { get; set; } = string.Empty; + + [Parameter] + public string Icon { get; set; } = "clipboard-check"; + + [Parameter] + public List<(string Label, bool IsGood, string? Notes)>? Items { get; set; } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Inspections/RoutineInspectionCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Inspections/RoutineInspectionCard.razor new file mode 100644 index 0000000..975c62f --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Inspections/RoutineInspectionCard.razor @@ -0,0 +1,148 @@ +@using Aquiis.Core.Entities + +
+
+
+ Routine Inspections +
+ @if (ShowScheduleButton && OnCompleteInspection.HasDelegate) + { + + } +
+
+
+ @if (LastInspection != null && LastInspection.Id != Guid.Empty) + { +
+
+
Last Inspection
+
+ +
+
@LastInspection.CompletedOn.ToString("MMMM dd, yyyy")
+ @GetDaysAgo(LastInspection.CompletedOn) +
+
+ @if (ShowLastInspectionDetails) + { +
+ Type: @LastInspection.InspectionType + @if (!string.IsNullOrEmpty(LastInspection.InspectedBy)) + { + Inspector: @LastInspection.InspectedBy + } +
+ @if (ShowViewButton && OnViewInspection.HasDelegate) + { + + } + } +
+
+ } + else + { +
+
+
Last Inspection
+

No inspections recorded.

+
+
+ } + +
+
Next Inspection
+ @if (NextInspectionDate.HasValue) + { +
+ @if (IsOverdue) + { + +
+
@NextInspectionDate.Value.ToString("MMMM dd, yyyy")
+ Overdue by @GetOverdueDays() days +
+ } + else if (IsDueSoon) + { + +
+
@NextInspectionDate.Value.ToString("MMMM dd, yyyy")
+ Due in @GetDaysUntil() days +
+ } + else + { + +
+
@NextInspectionDate.Value.ToString("MMMM dd, yyyy")
+ In @GetDaysUntil() days +
+ } +
+ } + else + { +

Not scheduled

+ @if (ShowScheduleButton && OnCompleteInspection.HasDelegate) + { + + } + } +
+
+
+
+ +@code { + [Parameter] + public Inspection? LastInspection { get; set; } + + [Parameter] + public DateTime? NextInspectionDate { get; set; } + + [Parameter] + public bool ShowScheduleButton { get; set; } = true; + + [Parameter] + public bool ShowViewButton { get; set; } = true; + + [Parameter] + public bool ShowLastInspectionDetails { get; set; } = true; + + [Parameter] + public EventCallback OnCompleteInspection { get; set; } + + [Parameter] + public EventCallback OnViewInspection { get; set; } + + private bool IsOverdue => NextInspectionDate.HasValue && NextInspectionDate.Value < DateTime.Today; + private bool IsDueSoon => NextInspectionDate.HasValue && NextInspectionDate.Value >= DateTime.Today && NextInspectionDate.Value <= DateTime.Today.AddDays(30); + + private string GetDaysAgo(DateTime date) + { + var days = (DateTime.Today - date.Date).Days; + if (days == 0) return "Today"; + if (days == 1) return "Yesterday"; + return $"{days} days ago"; + } + + private int GetDaysUntil() + { + if (!NextInspectionDate.HasValue) return 0; + return (NextInspectionDate.Value.Date - DateTime.Today).Days; + } + + private int GetOverdueDays() + { + if (!NextInspectionDate.HasValue) return 0; + return (DateTime.Today - NextInspectionDate.Value.Date).Days; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Invoices/InvoiceList.razor b/3-Aquiis.UI.Shared/Components/Entities/Invoices/InvoiceList.razor new file mode 100644 index 0000000..057863d --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Invoices/InvoiceList.razor @@ -0,0 +1,74 @@ +
+
+
@Title
+ +
+
+ @if (Invoices.Any()) + { +
+ @foreach (var invoice in Invoices.OrderByDescending(i => i.InvoiceNumber)) + { +
+
+
+ + @invoice.InvoiceNumber + +
+ @invoice.InvoicedOn.ToString("MMM dd, yyyy") +
+

@invoice.Lease?.Tenant?.FullName

+
+
+ Due: @invoice.DueOn.ToString("MMM dd, yyyy") + @if (invoice.IsOverdue) + { +
+ @invoice.DaysOverdue days overdue + } +
+
+ @invoice.Status +
+ @invoice.Amount.ToString("C") +
+
+
+ } +
+ } + else + { +

No outstanding invoices.

+ } +
+
+@code { + [Parameter, EditorRequired] + + public List Invoices { get; set; } = new(); + + [Parameter] + public string Title { get; set; } = "Invoices"; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public EventCallback OnViewAll { get; set; } + + [Parameter] + public EventCallback OnViewItem { get; set; } + + private string GetInvoiceStatusBadgeClass(string status) + { + return status switch + { + ApplicationConstants.InvoiceStatuses.Paid => "bg-success", + ApplicationConstants.InvoiceStatuses.PaidPartial => "bg-warning text-dark", + ApplicationConstants.InvoiceStatuses.Overdue => "bg-danger", + _ => "bg-secondary" + }; + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/ActiveLeaseCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/ActiveLeaseCard.razor new file mode 100644 index 0000000..b3c8679 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/ActiveLeaseCard.razor @@ -0,0 +1,187 @@ +@using Aquiis.Core.Entities + +
+
+
+ Active Lease +
+ @if (Lease != null && ShowViewButton && OnViewLease.HasDelegate) + { + + } +
+
+ @if (Lease == null) + { +
+ No active lease for this property. + @if (ShowCreateButton && OnCreateLease.HasDelegate) + { + + } +
+ } + else + { +
+
+
+ +
+ @if (Lease.Tenant != null) + { + @Lease.Tenant.FullName + @if (ShowTenantContact && !string.IsNullOrEmpty(Lease.Tenant.Email)) + { +
+ @Lease.Tenant.Email + } + @if (ShowTenantContact && !string.IsNullOrEmpty(Lease.Tenant.PhoneNumber)) + { +
+ @Lease.Tenant.PhoneNumber + } + } + else + { + Not assigned + } +
+
+
+
+
+ +
+ @Lease.Status +
+
+
+
+ +
+
+
+ +
+ + @Lease.StartDate.ToString("MMM dd, yyyy") to + @Lease.EndDate.ToString("MMM dd, yyyy") +
+ @GetRemainingDays() remaining +
+
+
+
+ +
+ @Lease.MonthlyRent.ToString("C") +
+
+
+
+ + @if (ShowFinancialDetails) + { +
+
+
+ +
@Lease.SecurityDeposit.ToString("C")
+
+
+
+ +
+
+ } + + @if (IsExpiringSoon) + { +
+ + Lease expiring soon! This lease expires in @GetDaysUntilExpiration() days. + @if (ShowRenewButton && OnRenewLease.HasDelegate) + { + + } +
+ } + } +
+
+ +@code { + [Parameter] + public Lease? Lease { get; set; } + + [Parameter] + public bool ShowViewButton { get; set; } = true; + + [Parameter] + public bool ShowCreateButton { get; set; } = true; + + [Parameter] + public bool ShowRenewButton { get; set; } = true; + + [Parameter] + public bool ShowTenantContact { get; set; } = true; + + [Parameter] + public bool ShowFinancialDetails { get; set; } = true; + + [Parameter] + public EventCallback OnViewLease { get; set; } + + [Parameter] + public EventCallback OnCreateLease { get; set; } + + [Parameter] + public EventCallback OnRenewLease { get; set; } + + private bool IsExpiringSoon => Lease != null && Lease.EndDate <= DateTime.Today.AddDays(60) && Lease.EndDate >= DateTime.Today; + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Active" => "bg-success", + "Pending" => "bg-warning", + "Expired" => "bg-danger", + "Terminated" => "bg-secondary", + "Offered" => "bg-info", + _ => "bg-secondary" + }; + } + + private string GetRemainingDays() + { + if (Lease == null) return ""; + + var days = (Lease.EndDate - DateTime.Today).Days; + + if (days < 0) + return "Expired"; + if (days == 0) + return "Expires today"; + if (days == 1) + return "1 day"; + if (days < 30) + return $"{days} days"; + + var months = days / 30; + return months == 1 ? "1 month" : $"{months} months"; + } + + private int GetDaysUntilExpiration() + { + if (Lease == null) return 0; + return (Lease.EndDate - DateTime.Today).Days; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseCard.razor new file mode 100644 index 0000000..e69de29 diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDetailsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDetailsCard.razor new file mode 100644 index 0000000..77a827e --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDetailsCard.razor @@ -0,0 +1,141 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Leases + +
+
+
Lease Information
+ + @Lease.Status + +
+
+
+
+ Property: +

@Lease.Property?.Address

+ @Lease.Property?.City, @Lease.Property?.State +
+
+ Tenant: + @if (Lease.Tenant != null) + { +

@Lease.Tenant.FullName

+ @Lease.Tenant.Email + } + else + { +

Lease Offer - Awaiting Acceptance

+ Tenant will be assigned upon acceptance + } +
+
+ +
+
+ Start Date: +

@Lease.StartDate.ToString("MMMM dd, yyyy")

+
+
+ End Date: +

@Lease.EndDate.ToString("MMMM dd, yyyy")

+
+
+ +
+
+ Monthly Rent: +

@Lease.MonthlyRent.ToString("C")

+
+
+ Security Deposit: +

@Lease.SecurityDeposit.ToString("C")

+
+
+ + @if (!string.IsNullOrEmpty(Lease.Terms)) + { +
+
+ Lease Terms: +

@Lease.Terms

+
+
+ } + + @if (!string.IsNullOrEmpty(Lease.Notes)) + { +
+
+ Notes: +

@Lease.Notes

+
+
+ } + +
+
+ Created: +

@Lease.CreatedOn.ToString("MMMM dd, yyyy")

+
+ @if (Lease.LastModifiedOn.HasValue) + { +
+ Last Modified: +

@Lease.LastModifiedOn.Value.ToString("MMMM dd, yyyy")

+
+ } +
+ + @if (Lease.IsActive) + { +
+
+
+ + Active Lease: This lease is currently active with @Lease.DaysRemaining days remaining. +
+
+
+ } +
+
+ +@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } + + private List recentInvoices = new List(); + + protected override void OnInitialized() + { + recentInvoices = Lease.Invoices? + .OrderByDescending(i => i.InvoicedOn) + .ToList() ?? new List(); + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Active" => "bg-success", + "Pending" => "bg-warning", + "Expired" => "bg-secondary", + "Terminated" => "bg-danger", + _ => "bg-secondary" + }; + } + + private string GetRenewalStatusBadgeClass(string status) + { + return status switch + { + "Pending" => "secondary", + "Offered" => "info", + "Accepted" => "success", + "Declined" => "danger", + "Expired" => "dark", + _ => "secondary" + }; + } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDocumentsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDocumentsCard.razor new file mode 100644 index 0000000..5bddf0c --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseDocumentsCard.razor @@ -0,0 +1,94 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Leases +@using Microsoft.AspNetCore.Http + +
+
+
Documents
+ @LeaseDocuments.Count +
+
+
+ @foreach (var doc in LeaseDocuments.OrderByDescending(d => d.CreatedOn)) + { +
+
+
+
+ + @doc.FileName +
+ @if (!string.IsNullOrEmpty(doc.Description)) + { + @doc.Description + } + + @doc.DocumentType + @doc.FileSizeFormatted | @doc.CreatedOn.ToString("MMM dd, yyyy") + +
+
+ + +
+
+
+ } +
+
+ +
+
+
+ +@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } = new Lease(); + + [Parameter, EditorRequired] + public List LeaseDocuments { get; set; } = new List(); + + private string GetFileIcon(string? extension) + { + return extension?.ToLower() switch + { + ".pdf" => "bi-file-earmark-pdf-fill text-danger", + ".doc" or ".docx" => "bi-file-earmark-word-fill text-primary", + ".xls" or ".xlsx" => "bi-file-earmark-excel-fill text-success", + ".png" or ".jpg" or ".jpeg" => "bi-file-earmark-image-fill text-warning", + _ => "bi-file-earmark-fill text-secondary", + }; + } + + private string GetDocumentTypeBadge(string documentType) + { + return documentType.ToLower() switch + { + "lease agreement" => "bg-primary", + "inspection report" => "bg-info", + "maintenance record" => "bg-warning", + _ => "bg-secondary", + }; + } + + private void ViewDocument(Document doc) + { + // Implement document viewing logic here + } + + private void DownloadDocument(Document doc) + { + // Implement document downloading logic here + } + + private void ViewDocuments() + { + // Implement navigation to documents page here + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseLifeCycleCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseLifeCycleCard.razor new file mode 100644 index 0000000..04afb9a --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseLifeCycleCard.razor @@ -0,0 +1,57 @@ + +
+@* Lease Lifecycle Management Card *@ +@if (Lease.Status == "Active" || Lease.Status == "MonthToMonth" || Lease.Status == "NoticeGiven") +{ +
+
+
Lease Management
+
+
+
+ @if (Lease.Status == "Active" || Lease.Status == "MonthToMonth") + { + + + + } + @if (Lease.Status == "NoticeGiven") + { +
+ + Notice Given: @Lease.TerminationNoticedOn?.ToString("MMM dd, yyyy")
+ Expected Move-Out: @Lease.ExpectedMoveOutDate?.ToString("MMM dd, yyyy") +
+
+ + + } +
+
+
+} +
+ +@code { + [Parameter] + public Lease Lease { get; set; } = new Lease(); + + [Parameter] + public EventCallback OnShowTerminationNoticeModal { get; set; } + [Parameter] + public EventCallback OnShowEarlyTerminationModal { get; set; } + [Parameter] + public EventCallback OnShowConvertMTMModal { get; set; } + [Parameter] + public EventCallback OnShowMoveOutModal { get; set; } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseList.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseList.razor new file mode 100644 index 0000000..8843e91 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseList.razor @@ -0,0 +1,178 @@ +
+
+
+ @Title +
+ + View All + +
+
+ @if (isLoading) + { +
+
+ Loading... +
+
+ } + else if (expiringLeases == null || !expiringLeases.Any()) + { +

No leases expiring in the next 90 days.

+ } + else + { +
+
+ + + + + + + + +
+
+ +
+ @foreach (var lease in GetFilteredLeases()) + { + var daysRemaining = (lease.EndDate - DateTime.Today).Days; + var urgencyClass = daysRemaining <= 30 ? "danger" : daysRemaining <= 60 ? "warning" : "info"; + var urgencyIcon = daysRemaining <= 30 ? "exclamation-triangle-fill" : daysRemaining <= 60 ? "exclamation-circle-fill" : "info-circle-fill"; + +
+
+
+
+ + @lease.Property?.Address +
+

+ Tenant: @lease.Tenant?.FullName
+ End Date: @lease.EndDate.ToString("MMM dd, yyyy")
+ Current Rent: @lease.MonthlyRent.ToString("C") + @if (lease.ProposedRenewalRent.HasValue) + { + → @lease.ProposedRenewalRent.Value.ToString("C") + } +

+ @if (!string.IsNullOrEmpty(lease.RenewalStatus)) + { + + @lease.RenewalStatus + + } +
+
+ + @daysRemaining days + +
+
+
+ } +
+ + + } +
+
+ +@code { + [Parameter] + public string Title { get; set; } = "Leases"; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public List Leases { get; set; } = new(); + + private List expiringLeases = new(); + private List leases30Days = new(); + private List leases60Days = new(); + private List leases90Days = new(); + private bool isLoading = true; + private int selectedFilter = 30; + + + private async Task LoadExpiringLeases() + { + try + { + isLoading = true; + var today = DateTime.Today; + + expiringLeases = Leases + .Where(l => l.Status == "Active" && + l.EndDate >= today && + l.EndDate <= today.AddDays(90)) + .OrderBy(l => l.EndDate) + .ToList(); + + leases30Days = expiringLeases + .Where(l => l.EndDate <= today.AddDays(30)) + .ToList(); + + leases60Days = expiringLeases + .Where(l => l.EndDate <= today.AddDays(60)) + .ToList(); + + leases90Days = expiringLeases; + } + catch (Exception ex) + { + // Log error + Console.WriteLine($"Error loading expiring leases: {ex.Message}"); + } + finally + { + isLoading = false; + } + } + + private void FilterLeases(int days) + { + selectedFilter = days; + } + + private List GetFilteredLeases() + { + return selectedFilter switch + { + 30 => leases30Days, + 60 => leases60Days, + 90 => leases90Days, + _ => expiringLeases + }; + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Pending" => "secondary", + "Offered" => "info", + "Accepted" => "success", + "Declined" => "danger", + "Expired" => "dark", + _ => "secondary" + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseListView.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseListView.razor new file mode 100644 index 0000000..c0480aa --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseListView.razor @@ -0,0 +1,400 @@ +@namespace Aquiis.UI.Shared.Components.Entities.Leases +@using Aquiis.Core.Entities +@using Aquiis.UI.Shared.Components.Common + + +@if (ShowMetrics) +{ + + + +} + + + + + + + + + +
+
+ @if (GroupByProperty) + { + @foreach (var propertyGroup in GroupedLeases) + { + var property = propertyGroup.First().Property; + var propertyLeaseCount = propertyGroup.Count(); + var activeLeaseCount = propertyGroup.Count(l => l.Status == "Active"); + var isExpanded = ExpandedProperties.Contains(propertyGroup.Key.GetHashCode()); + +
+
+
+
+ + @property?.Address + @property?.City, @property?.State @property?.ZipCode +
+
+ @activeLeaseCount active + @propertyLeaseCount total lease(s) +
+
+
+ @if (isExpanded) + { +
+ + + + + + + + + @if (ShowActions) + { + + } + + + + @foreach (var lease in propertyGroup) + { + + + + + + + @if (ShowActions) + { + + } + + } + +
TenantStart DateEnd DateMonthly RentStatusActions
+ @if (lease.Tenant != null) + { + @lease.Tenant.FullName +
+ @lease.Tenant.Email + } + else + { + Pending Acceptance +
+ Lease offer awaiting tenant + } +
@lease.StartDate.ToString("MMM dd, yyyy")@lease.EndDate.ToString("MMM dd, yyyy")@lease.MonthlyRent.ToString("C") + + @lease.Status + + @if (lease.IsActive && lease.DaysRemaining <= 30 && lease.DaysRemaining > 0) + { +
+ @lease.DaysRemaining days remaining + } +
+
+ + @if (ShowEditDelete) + { + + + } +
+
+
+ } +
+ } + } + else + { +
+ + + + + + + + + + @if (ShowActions) + { + + } + + + + @foreach (var lease in Leases) + { + + + + + + + + @if (ShowActions) + { + + } + + } + +
+ Property + @if (SortColumn == nameof(Lease.Property)) + { + + } + + Tenant + @if (SortColumn == nameof(Lease.Tenant)) + { + + } + + Start Date + @if (SortColumn == nameof(Lease.StartDate)) + { + + } + + End Date + @if (SortColumn == nameof(Lease.EndDate)) + { + + } + + Monthly Rent + @if (SortColumn == nameof(Lease.MonthlyRent)) + { + + } + + Status + @if (SortColumn == nameof(Lease.Status)) + { + + } + Actions
+ @lease.Property?.Address + @if (lease.Property != null) + { +
+ @lease.Property.City, @lease.Property.State + } +
+ @if (lease.Tenant != null) + { + @lease.Tenant.FullName +
+ @lease.Tenant.Email + } + else + { + Pending Acceptance +
+ Lease offer awaiting tenant + } +
@lease.StartDate.ToString("MMM dd, yyyy")@lease.EndDate.ToString("MMM dd, yyyy")@lease.MonthlyRent.ToString("C") + + @lease.Status + + @if (lease.IsActive && lease.DaysRemaining <= 30 && lease.DaysRemaining > 0) + { +
+ @lease.DaysRemaining days remaining + } +
+
+ + @if (ShowEditDelete) + { + + + } +
+
+
+ } +
+
+ +@code { + [Parameter, EditorRequired] + public List Leases { get; set; } = new(); + + [Parameter] + public IEnumerable> GroupedLeases { get; set; } = Enumerable.Empty>(); + + [Parameter] + public List AvailableTenants { get; set; } = new(); + + [Parameter] + public HashSet ExpandedProperties { get; set; } = new(); + + [Parameter] + public bool GroupByProperty { get; set; } = false; + + [Parameter] + public bool ShowMetrics { get; set; } = true; + + [Parameter] + public bool ShowActions { get; set; } = true; + + [Parameter] + public bool ShowEditDelete { get; set; } = true; + + [Parameter] + public string SearchTerm { get; set; } = string.Empty; + + [Parameter] + public string StatusFilter { get; set; } = string.Empty; + + [Parameter] + public string TenantFilter { get; set; } = string.Empty; + + [Parameter] + public string SortColumn { get; set; } = nameof(Lease.StartDate); + + [Parameter] + public bool SortAscending { get; set; } = false; + + [Parameter] + public int ActiveCount { get; set; } + + [Parameter] + public int ExpiringSoonCount { get; set; } + + [Parameter] + public decimal TotalMonthlyRent { get; set; } + + [Parameter] + public EventCallback OnSearchChanged { get; set; } + + [Parameter] + public EventCallback OnStatusFilterChanged { get; set; } + + [Parameter] + public EventCallback OnTenantFilterChanged { get; set; } + + [Parameter] + public EventCallback OnGroupByPropertyChanged { get; set; } + + [Parameter] + public EventCallback<(string Column, bool Ascending)> OnSort { get; set; } + + [Parameter] + public EventCallback OnTogglePropertyGroup { get; set; } + + [Parameter] + public EventCallback OnView { get; set; } + + [Parameter] + public EventCallback OnEdit { get; set; } + + [Parameter] + public EventCallback OnDelete { get; set; } + + // Lease status options for filter dropdown + private List leaseStatuses = new() { "Active", "Expired", "Terminated", "Pending" }; + + private async Task HandleSearchChanged(string searchTerm) + { + await OnSearchChanged.InvokeAsync(searchTerm); + } + + private async Task HandleStatusFilterChanged(string status) + { + await OnStatusFilterChanged.InvokeAsync(status); + } + + private async Task HandleTenantFilterChanged(ChangeEventArgs e) + { + await OnTenantFilterChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleGroupByPropertyChanged(bool groupByProperty) + { + await OnGroupByPropertyChanged.InvokeAsync(groupByProperty); + } + + private async Task HandleSort(string column) + { + var ascending = SortColumn == column ? !SortAscending : true; + await OnSort.InvokeAsync((column, ascending)); + } + + private async Task HandleTogglePropertyGroup(Guid propertyId) + { + await OnTogglePropertyGroup.InvokeAsync(propertyId); + } + + private async Task HandleView(Guid leaseId) + { + await OnView.InvokeAsync(leaseId); + } + + private async Task HandleEdit(Guid leaseId) + { + await OnEdit.InvokeAsync(leaseId); + } + + private async Task HandleDelete(Guid leaseId) + { + await OnDelete.InvokeAsync(leaseId); + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Active" => "bg-success", + "Pending" => "bg-info", + "Expired" => "bg-warning", + "Terminated" => "bg-danger", + _ => "bg-secondary" + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseMetricsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseMetricsCard.razor new file mode 100644 index 0000000..6623422 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseMetricsCard.razor @@ -0,0 +1,64 @@ +
+ @if(ShowActive){ +
+
+
+
Active Leases
+

@ActiveCount

+
+
+
+ } + @if(ShowExpiringSoon){ +
+
+
+
Expiring Soon
+

@ExpiringSoonCount

+
+
+
+ } + @if(ShowTotalCount){ +
+
+
+
Total Leases
+

@TotalCount

+
+
+
+ } + @if(ShowTotalMonthlyRent){ +
+
+
+
Total Rent/Month
+

@TotalMonthlyRent.ToString("C")

+
+
+
+ } +
+@code { + [Parameter] + public int ActiveCount { get; set; } + + [Parameter] + public int ExpiringSoonCount { get; set; } + + [Parameter] + public decimal TotalMonthlyRent { get; set; } + + [Parameter] + public int TotalCount { get; set; } + + [Parameter] + public bool ShowActive { get; set; } = false; + [Parameter] + public bool ShowExpiringSoon { get; set; } = false; + [Parameter] + public bool ShowTotalMonthlyRent { get; set; } = false; + [Parameter] + public bool ShowTotalCount { get; set; } = false; +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeasePaymentsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeasePaymentsCard.razor new file mode 100644 index 0000000..283047e --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeasePaymentsCard.razor @@ -0,0 +1,51 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Leases + +
+
+
Invoice Payments
+
+
+ @if (InvoicePayments != null && InvoicePayments.Any()) + { +
+ @foreach (var payment in InvoicePayments.OrderByDescending(p => p.PaidOn)) + { +
+
+
+
+ @payment.InvoiceId +
+ + @payment.Amount.ToString("C") | @payment.PaidOn.ToString("MMM dd, yyyy") + +
+
+ +
+
+
+ } +
+ } + else + { +

No payments found for this lease.

+ } +
+
+ + +@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } + + [Parameter, EditorRequired] + public IEnumerable InvoicePayments { get; set; } + + [Parameter] + public EventCallback OnViewPayment { get; set; } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseQuickActionsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseQuickActionsCard.razor new file mode 100644 index 0000000..b24e96c --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseQuickActionsCard.razor @@ -0,0 +1,74 @@ + +
+
+
Quick Actions
+
+
+
+ + + + + @if (Lease.DocumentId == null) + { + + } + else + { + + + } +
+
+
+ +@code { + [Parameter] + public Lease Lease { get; set; } = new Lease(); + + [Parameter] + public EventCallback OnEdit { get; set; } + + [Parameter] + public EventCallback OnCreateInvoice { get; set; } + + [Parameter] + public EventCallback OnViewInvoices { get; set; } + + [Parameter] + public EventCallback OnViewDocuments { get; set; } + + [Parameter] + public EventCallback OnGenerateLeaseDocument { get; set; } + + [Parameter] + public EventCallback OnViewDocument { get; set; } + + [Parameter] + public EventCallback OnDownloadDocument { get; set; } + [Parameter] + public bool IsGenerating { get; set; } = false; +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalCard.razor new file mode 100644 index 0000000..1b1dc88 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalCard.razor @@ -0,0 +1,164 @@ +
+ @if (Lease.IsExpiringSoon) + { +
+
+
+ Renewal Alert +
+
+
+

+ Expires in: + @Lease.DaysRemaining days +

+

+ End Date: @Lease.EndDate.ToString("MMM dd, yyyy") +

+ + @if (!string.IsNullOrEmpty(Lease.RenewalStatus)) + { +

+ Status: + + @Lease.RenewalStatus + +

+ } + + @if (Lease.ProposedRenewalRent.HasValue) + { +

+ Proposed Rent: @Lease.ProposedRenewalRent.Value.ToString("C") + @if (Lease.ProposedRenewalRent != Lease.MonthlyRent) + { + var increase = Lease.ProposedRenewalRent.Value - Lease.MonthlyRent; + var percentage = (increase / Lease.MonthlyRent) * 100; + + (@(increase > 0 ? "+" : "")@increase.ToString("C"), @percentage.ToString("F1")%) + + } +

+ } + + @if (Lease.RenewalNotificationSentOn.HasValue) + { + + Notification sent: @Lease.RenewalNotificationSentOn.Value.ToString("MMM dd, yyyy") + + } + + @if (!string.IsNullOrEmpty(Lease.RenewalNotes)) + { +
+ + Notes:
+ @Lease.RenewalNotes +
+ } + +
+ @if (Lease.RenewalStatus == "Pending" || string.IsNullOrEmpty(Lease.RenewalStatus)) + { + + + } + @if (Lease.RenewalStatus == "Offered") + { + + + + } +
+
+
+ } +
+ +@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } + + private bool isGeneratingPdf = false; + + private void ShowRenewalOfferModal() + { + // Logic to show modal for sending renewal offer + } + + private async Task GenerateRenewalOfferPdf() + { + isGeneratingPdf = true; + try + { + // Logic to generate PDF + await Task.Delay(2000); // Simulate PDF generation delay + } + finally + { + isGeneratingPdf = false; + } + } + + private void MarkRenewalAccepted() + { + // Logic to mark renewal as accepted + } + + private void MarkRenewalDeclined() + { + // Logic to mark renewal as declined + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Active" => "bg-success", + "Pending" => "bg-warning", + "Expired" => "bg-secondary", + "Terminated" => "bg-danger", + _ => "bg-secondary" + }; + } + + private string GetRenewalStatusBadgeClass(string status) + { + return status switch + { + "Pending" => "secondary", + "Offered" => "info", + "Accepted" => "success", + "Declined" => "danger", + "Expired" => "dark", + _ => "secondary" + }; + } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalList.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalList.razor new file mode 100644 index 0000000..26b938b --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseRenewalList.razor @@ -0,0 +1,189 @@ +@namespace Aquiis.UI.Shared.Components.Entities.Leases +
+
+
+ @Title +
+ +
+
+ @if (isLoading) + { +
+
+ Loading... +
+
+ } + else if (Leases == null || !Leases.Any()) + { +

No leases expiring in the next 90 days.

+ } + else + { +
+
+ + + + + + + + +
+
+ +
+ @foreach (var lease in GetFilteredLeases()) + { + var daysRemaining = (lease.EndDate - DateTime.Today).Days; + var urgencyClass = daysRemaining <= 30 ? "danger" : daysRemaining <= 60 ? "warning" : "info"; + var urgencyIcon = daysRemaining <= 30 ? "exclamation-triangle-fill" : daysRemaining <= 60 ? "exclamation-circle-fill" : "info-circle-fill"; + +
+
+
+
+ + @lease.Property?.Address +
+

+ Tenant: @lease.Tenant?.FullName
+ End Date: @lease.EndDate.ToString("MMM dd, yyyy")
+ Current Rent: @lease.MonthlyRent.ToString("C") + @if (lease.ProposedRenewalRent.HasValue) + { + → @lease.ProposedRenewalRent.Value.ToString("C") + } +

+ @if (!string.IsNullOrEmpty(lease.RenewalStatus)) + { + + @lease.RenewalStatus + + } +
+
+ + @daysRemaining days + +
+
+
+ } +
+ + + } +
+
+ +@code { + + [Parameter] + public string Title { get; set; } = "Upcoming Lease Renewals"; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public List Leases { get; set; } = new(); + + private List leases30Days = new(); + private List leases60Days = new(); + private List leases90Days = new(); + private bool isLoading = true; + private int selectedFilter = 60; + + [Parameter] + public EventCallback OnViewAll { get; set; } + + [Parameter] + public EventCallback OnViewLease { get; set; } + + [Parameter] + public EventCallback OnFilterChanged { get; set; } + + protected override async Task OnInitializedAsync() + { + await LoadLeases(); + } + + private async Task LoadLeases() + { + try + { + isLoading = true; + var today = DateTime.Today; + + leases30Days = Leases + .Where(l => l.EndDate <= today.AddDays(30)) + .ToList(); + + leases60Days = Leases + .Where(l => l.EndDate <= today.AddDays(60)) + .ToList(); + + leases90Days = Leases + .Where(l => l.EndDate <= today.AddDays(90)) + .ToList(); + } + catch (Exception ex) + { + // Log error + Console.WriteLine($"Error loading expiring leases: {ex.Message}"); + } + finally + { + isLoading = false; + } + } + + private async Task FilterLeases(int days) + { + selectedFilter = days; + await OnFilterChanged.InvokeAsync(days); + StateHasChanged(); + } + + private List GetFilteredLeases() + { + return selectedFilter switch + { + 30 => leases30Days, + 60 => leases60Days, + 90 => leases90Days, + _ => Leases + }; + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + "Pending" => "secondary", + "Offered" => "info", + "Accepted" => "success", + "Declined" => "danger", + "Expired" => "dark", + _ => "secondary" + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSearchAndFilter.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSearchAndFilter.razor new file mode 100644 index 0000000..926639f --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSearchAndFilter.razor @@ -0,0 +1,104 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Leases + +
+
+
+ + +
+
+
+ +
+
+ +
+ @if (AllowGrouping) + { +
+
+ + +
+
+ } +
+@code { + [Parameter] + public string SearchTerm { get; set; } = string.Empty; + + [Parameter] + public string StatusFilter { get; set; } = string.Empty; + + [Parameter] + public Guid TenantFilter { get; set; } = Guid.Empty; + + [Parameter] + public List AvailableTenants { get; set; } = new(); + + [Parameter] + public EventCallback OnSearchChanged { get; set; } + + [Parameter] + public EventCallback OnStatusFilterChanged { get; set; } + + [Parameter] + public EventCallback OnTenantFilterChanged { get; set; } + + [Parameter] + public bool GroupByProperty { get; set; } = false; + + [Parameter] + public bool AllowGrouping { get; set; } = true; + + [Parameter] + public EventCallback OnGroupByPropertyChanged { get; set; } + + private async Task HandleSearchChanged(ChangeEventArgs e) + { + var value = e.Value?.ToString() ?? string.Empty; + await OnSearchChanged.InvokeAsync(value); + } + + private async Task HandleStatusFilterChanged(ChangeEventArgs e) + { + var value = e.Value?.ToString() ?? string.Empty; + await OnStatusFilterChanged.InvokeAsync(value); + } + + private async Task HandleTenantFilterChanged(ChangeEventArgs e) + { + var value = e.Value?.ToString() ?? string.Empty; + Guid tenantId = Guid.Empty; + if (Guid.TryParse(value, out var parsedId)) + { + tenantId = parsedId; + } + await OnTenantFilterChanged.InvokeAsync(tenantId); + } + private async Task HandleGroupByPropertyChanged(ChangeEventArgs e) + { + var value = e.Value?.ToString() ?? "false"; + bool isChecked = bool.TryParse(value, out var parsed) && parsed; + await OnGroupByPropertyChanged.InvokeAsync(isChecked); + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSummaryCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSummaryCard.razor new file mode 100644 index 0000000..8c34ab3 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseSummaryCard.razor @@ -0,0 +1,42 @@ + +
+ @* Lease Summary Card *@ +
+
+
Lease Summary
+
+
+

Duration: @((Lease.EndDate - Lease.StartDate).Days) days

+

Total Rent: @((Lease.MonthlyRent * 12).ToString("C"))/year

+ @if (Lease.IsActive) + { +

Days Remaining: @Lease.DaysRemaining

+ } + @if (RecentInvoices.Any()) + { +
+ + Recent Invoices:
+ @foreach (var invoice in RecentInvoices.Take(3)) + { + + @invoice.InvoiceNumber + + } +
+ } +
+
+
+@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } = new Lease(); + + [Parameter] + public EventCallback OnViewInvoice { get; set; } + + [Parameter] + public List RecentInvoices { get; set; } = new List(); + + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseTransactionsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseTransactionsCard.razor new file mode 100644 index 0000000..9df95fc --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Leases/LeaseTransactionsCard.razor @@ -0,0 +1,58 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Leases + +
+
+
Lease Invoices
+ @LeaseInvoices.Count +
+
+
+ @foreach (var invoice in LeaseInvoices.OrderByDescending(i => i.InvoiceNumber)) + { +
+
+
+ + + @invoice.BalanceDue.ToString("C") | @invoice.InvoicedOn.ToString("MMM dd, yyyy") + +
+
+ + @if(invoice.BalanceDue > 0) + { + + } +
+
+
+ } +
+
+
+ + + + + + +@code { + [Parameter, EditorRequired] + public Lease Lease { get; set; } = new Lease(); + + [Parameter, EditorRequired] + public List LeaseInvoices { get; set; } = new List(); + + [Parameter, EditorRequired] + public EventCallback OnViewInvoice { get; set; } + + [Parameter, EditorRequired] + public EventCallback OnMakePayment { get; set; } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestCard.razor b/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestCard.razor new file mode 100644 index 0000000..e69de29 diff --git a/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestDetails.razor b/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestDetails.razor new file mode 100644 index 0000000..e69de29 diff --git a/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestForm.razor b/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestForm.razor new file mode 100644 index 0000000..e69de29 diff --git a/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestListView.razor b/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestListView.razor new file mode 100644 index 0000000..decfb2c --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/MaintenanceRequests/MaintenanceRequestListView.razor @@ -0,0 +1,104 @@ + +@inject NavigationManager Navigation +@namespace Aquiis.UI.Shared.Components.Entities.MaintenanceRequests +@using Microsoft.AspNetCore.Http + +
+
+
Maintenance Requests
+ +
+
+ @if (MaintenanceRequests.Any()) + { +
+ @foreach (var request in MaintenanceRequests.OrderByDescending(r => r.RequestedOn).Take(5)) + { +
+
+
+
+ @request.Title + @request.Priority + @request.Status + @if (request.IsOverdue) + { + + } +
+ @request.RequestType + + Requested: @request.RequestedOn.ToString("MMM dd, yyyy") + @if (request.ScheduledOn.HasValue) + { + | Scheduled: @request.ScheduledOn.Value.ToString("MMM dd, yyyy") + } + +
+ +
+
+ } +
+ @if (MaintenanceRequests.Count > 5) + { +
+ Showing 5 of @MaintenanceRequests.Count requests +
+ } +
+ +
+ } + else + { +
+ +

No maintenance requests for this property

+ +
+ } +
+
+@code { + [Parameter, EditorRequired] + public List MaintenanceRequests { get; set; } = default!; + + [Parameter, EditorRequired] + public Guid PropertyId { get; set; } + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public EventCallback OnViewRequest { get; set; } + + [Parameter] + public EventCallback OnCreateRequest { get; set; } + + [Parameter] + public EventCallback OnViewAllRequests { get; set; } + + private void CreateMaintenanceRequest() + { + OnCreateRequest.InvokeAsync(); + } + + private void ViewMaintenanceRequest(Guid requestId) + { + OnViewRequest.InvokeAsync(requestId); + } + + private void ViewAllMaintenanceRequests() + { + OnViewAllRequests.InvokeAsync(); + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/OrganizationUserViewModel.cs b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/OrganizationUserViewModel.cs new file mode 100644 index 0000000..917a532 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/OrganizationUserViewModel.cs @@ -0,0 +1,32 @@ +using Aquiis.Core.Entities; + +namespace Aquiis.UI.Shared.Components.Entities.OrganizationUsers; + + +/// +/// View model representing a user's membership in an organization. +/// Combines data from OrganizationUser entity and ApplicationUser (AspNetUsers). +/// +public class OrganizationUserViewModel +{ + // From OrganizationUser entity + public Guid Id { get; set; } // OrganizationUser.Id + public Guid OrganizationId { get; set; } + public string UserId { get; set; } = string.Empty; + public string Role { get; set; } = string.Empty; + public bool IsActive { get; set; } + public DateTime GrantedOn { get; set; } + public DateTime? RevokedOn { get; set; } + public string? GrantedBy { get; set; } // UserId of granter + public string? GrantedByEmail { get; set; } // Email of granter (from UserProfile join) + + // From UserProfile + public string Email { get; set; } = string.Empty; + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public string? PhoneNumber { get; set; } + + // Computed properties + public string FullName => $"{FirstName} {LastName}".Trim(); + public string DisplayRole => Role; +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserAccessCard.razor b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserAccessCard.razor new file mode 100644 index 0000000..412d251 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserAccessCard.razor @@ -0,0 +1,55 @@ + +@using Aquiis.Core.Entities +@using Aquiis.Core.Constants +@namespace Aquiis.UI.Shared.Components.Entities.OrganizationUsers + + +
+
+
Your Access
+
+
+

Your Role:

+

+ + @CurrentUserRole + +

+
+

+ @if (isOwner) + { + You have full control over this organization as the Owner. + } + else if (isAdministrator) + { + You have administrative access to this organization. + } + else + { + You have limited access to this organization. + } +

+
+
+ +@code { + + [Parameter, EditorRequired] + public string CurrentUserRole { get; set; } + + private bool isOwner => CurrentUserRole == ApplicationConstants.OrganizationRoles.Owner; + private bool isAdministrator => CurrentUserRole == ApplicationConstants.OrganizationRoles.Administrator; + + private string GetRoleBadgeClass(string role) + { + return role switch + { + ApplicationConstants.OrganizationRoles.Owner => "bg-primary", + ApplicationConstants.OrganizationRoles.Administrator => "bg-info", + ApplicationConstants.OrganizationRoles.PropertyManager => "bg-success", + ApplicationConstants.OrganizationRoles.User => "bg-secondary", + _ => "bg-secondary" + }; + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserProfileCard.razor b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserProfileCard.razor new file mode 100644 index 0000000..a19e4d4 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/OrganizationUsers/UserProfileCard.razor @@ -0,0 +1,25 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.OrganizationUsers + +
+
+
+ +
+
+
@OrganizationUserViewModel!.FirstName @OrganizationUserViewModel!.LastName
+

Email: @OrganizationUserViewModel!.Email

+

Role: @OrganizationUserViewModel!.Role

+
+
+
+ +@code { + + [Parameter, EditorRequired] + public OrganizationUserViewModel? OrganizationUserViewModel { get; set; } = new(); + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationCard.razor new file mode 100644 index 0000000..e5f767e --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationCard.razor @@ -0,0 +1,72 @@ +@using Aquiis.Core.Entities +@using Aquiis.Application.Services +@using Aquiis.Core.Constants + +@namespace Aquiis.UI.Shared.Components.Entities.Organizations + + +
+
+
Organization Information
+ +
+ @if(OrganizationViewModel?.Organization != null) + { +
+
+
Organization Name:
+
@OrganizationViewModel?.Organization?.Name
+ +
Display Name:
+
@(OrganizationViewModel?.Organization?.DisplayName ?? "-")
+ +
State:
+
@(OrganizationViewModel?.Organization?.State ?? "-")
+ +
Status:
+
+ @if (OrganizationViewModel?.Organization?.IsActive == true) + { + Active + } + else + { + Inactive + } +
+ +
Owner:
+
@OrganizationViewModel?.OrganizationOwner?.Email
+ +
Created On:
+
@OrganizationViewModel?.Organization?.CreatedOn.ToString("MMMM dd, yyyy")
+ + @if (OrganizationViewModel?.Organization?.LastModifiedOn.HasValue == true) + { +
Last Modified:
+
@OrganizationViewModel?.Organization?.LastModifiedOn.Value.ToString("MMMM dd, yyyy")
+ } +
+
+ } + else + { +
+
+ Organization details are not available. +
+
+ } +
+ +@code { + + [Parameter, EditorRequired] + public OrganizationViewModel? OrganizationViewModel { get; set; } = new(); + + [Parameter] + public EventCallback OnEdit { get; set; } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUserStatistics.razor b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUserStatistics.razor new file mode 100644 index 0000000..c08fe30 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUserStatistics.razor @@ -0,0 +1,34 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Organizations +@using Aquiis.UI.Shared.Components.Entities.OrganizationUsers + +
+
+
Quick Stats
+
+
+
+
Total Users:
+
@OrganizationUsers.Count
+ +
Active Users:
+
@OrganizationUsers.Count(u => u.IsActive)
+ +
Owners:
+
@OrganizationUsers.Count(u => u.Role == ApplicationConstants.OrganizationRoles.Owner)
+ +
Administrators:
+
@OrganizationUsers.Count(u => u.Role == ApplicationConstants.OrganizationRoles.Administrator)
+ +
Property Managers:
+
@OrganizationUsers.Count(u => u.Role == ApplicationConstants.OrganizationRoles.PropertyManager)
+
+
+
+ +@code { + [Parameter, EditorRequired] + public OrganizationViewModel OrganizationViewModel { get; set; } + + public List OrganizationUsers => OrganizationViewModel.OrganizationUsers; +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUsersListView.razor b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUsersListView.razor new file mode 100644 index 0000000..eacc86b --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationUsersListView.razor @@ -0,0 +1,101 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Organizations +@using Aquiis.UI.Shared.Components.Entities.OrganizationUsers + + +
+
+
Users with Access
+ @if (IsOwner || IsAdministrator && IsCurrentOrganization) + { + + } +
+
+ @if (!OrganizationUsers.Any()) + { +
+ No users assigned to this organization. +
+ } + else + { +
+ + + + + + + + + + + + @foreach (var orgUser in OrganizationUsers) + { + + + + + + + + } + +
UserRoleGranted ByGranted OnStatus
+
+ @orgUser.Email +
+
+ + @orgUser.Role + + @(orgUser.GrantedByEmail ?? "Unknown")@orgUser.GrantedOn.ToString("MMM dd, yyyy") + @if (orgUser.IsActive && orgUser.RevokedOn == null) + { + Active + } + else + { + Revoked + } +
+
+ } +
+
+ +@code { + + [Parameter, EditorRequired] + public OrganizationViewModel? OrganizationViewModel { get; set; } = new(); + + public List OrganizationUsers => OrganizationViewModel?.OrganizationUsers ?? new List(); + + [Parameter, EditorRequired] + public bool IsOwner { get; set; } = false; + [Parameter, EditorRequired] + public bool IsAdministrator { get; set; } = false; + + [Parameter, EditorRequired] + public bool IsCurrentOrganization { get; set; } = false; + + [Parameter] + public EventCallback OnManageUsers { get; set; } + + private string GetRoleBadgeClass(string role) + { + return role switch + { + ApplicationConstants.OrganizationRoles.Owner => "bg-primary", + ApplicationConstants.OrganizationRoles.Administrator => "bg-info", + ApplicationConstants.OrganizationRoles.PropertyManager => "bg-success", + ApplicationConstants.OrganizationRoles.User => "bg-secondary", + _ => "bg-secondary" + }; + } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationViewModel.cs b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationViewModel.cs new file mode 100644 index 0000000..1c454bf --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Organizations/OrganizationViewModel.cs @@ -0,0 +1,11 @@ +using Aquiis.Core.Entities; +using Aquiis.UI.Shared.Components.Entities.OrganizationUsers; + +namespace Aquiis.UI.Shared.Components.Entities.Organizations; + +public class OrganizationViewModel +{ + public Organization? Organization { get; set; } + public OrganizationUserViewModel? OrganizationOwner { get; set; } + public List OrganizationUsers { get; set; } = new(); +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyCard.razor new file mode 100644 index 0000000..6c5eeea --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyCard.razor @@ -0,0 +1,198 @@ +@namespace Aquiis.UI.Shared.Components.Entities.Properties +@using Aquiis.Core.Entities +@using Aquiis.Core.Constants + +
+
+
+
@Address
+ + @Status + +
+

@City, @State @ZipCode

+ + @if (!string.IsNullOrWhiteSpace(Description)) + { +

@Description

+ } + +
+
+ Bedrooms +
@Bedrooms
+
+
+ Bathrooms +
@Bathrooms
+
+
+ Sq Ft +
@SquareFeet.ToString("N0")
+
+
+ +
+ @MonthlyRent.ToString("C") + /month +
+
+ + @if (ShowActions) + { + + } +
+ +@code { + /// + /// Property ID + /// + [Parameter, EditorRequired] + public Guid PropertyId { get; set; } + + /// + /// Property address + /// + [Parameter, EditorRequired] + public string Address { get; set; } = string.Empty; + + /// + /// Unit number (optional) + /// + [Parameter] + public string? UnitNumber { get; set; } + + /// + /// City + /// + [Parameter, EditorRequired] + public string City { get; set; } = string.Empty; + + /// + /// State + /// + [Parameter, EditorRequired] + public string State { get; set; } = string.Empty; + + /// + /// Zip code + /// + [Parameter, EditorRequired] + public string ZipCode { get; set; } = string.Empty; + + /// + /// Property description + /// + [Parameter] + public string? Description { get; set; } + + /// + /// Number of bedrooms + /// + [Parameter] + public int Bedrooms { get; set; } + + /// + /// Number of bathrooms + /// + [Parameter] + public decimal Bathrooms { get; set; } + + /// + /// Square footage + /// + [Parameter] + public int SquareFeet { get; set; } + + /// + /// Monthly rent amount + /// + [Parameter] + public decimal MonthlyRent { get; set; } + + /// + /// Property status + /// + [Parameter, EditorRequired] + public string Status { get; set; } = string.Empty; + + /// + /// Whether to show action buttons + /// + [Parameter] + public bool ShowActions { get; set; } = true; + + /// + /// Whether to show edit/delete buttons (requires ShowActions = true) + /// + [Parameter] + public bool ShowEditDelete { get; set; } = true; + + /// + /// Callback when View button is clicked + /// + [Parameter] + public EventCallback OnView { get; set; } + + /// + /// Callback when Edit button is clicked + /// + [Parameter] + public EventCallback OnEdit { get; set; } + + /// + /// Callback when Delete button is clicked + /// + [Parameter] + public EventCallback OnDelete { get; set; } + + private string DisplayAddress => string.IsNullOrWhiteSpace(UnitNumber) + ? Address + : $"{Address}, {UnitNumber}"; + + private async Task HandleView() + { + await OnView.InvokeAsync(PropertyId); + } + + private async Task HandleEdit() + { + await OnEdit.InvokeAsync(PropertyId); + } + + private async Task HandleDelete() + { + await OnDelete.InvokeAsync(PropertyId); + } + + private string GetStatusBadgeClass() + { + return Status switch + { + var s when s == ApplicationConstants.PropertyStatuses.Available => "bg-success", + var s when s == ApplicationConstants.PropertyStatuses.ApplicationPending => "bg-info", + var s when s == ApplicationConstants.PropertyStatuses.LeasePending => "bg-warning", + var s when s == ApplicationConstants.PropertyStatuses.Occupied => "bg-danger", + var s when s == ApplicationConstants.PropertyStatuses.UnderRenovation => "bg-secondary", + var s when s == ApplicationConstants.PropertyStatuses.OffMarket => "bg-dark", + _ => "bg-secondary" + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyDetails.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyDetails.razor new file mode 100644 index 0000000..26907dc --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyDetails.razor @@ -0,0 +1,114 @@ +@namespace Aquiis.UI.Shared.Components.Entities.Properties +@using Aquiis.Core.Entities +@using Aquiis.Core.Constants + +
+
+
Property Information
+ + @Property.Status + + @if (OnEdit.HasDelegate) + { + + } +
+
+
+
+ Address: +

@Property.Address @(!string.IsNullOrWhiteSpace(Property.UnitNumber) ? $", {Property.UnitNumber}" : "")

+ @Property.City, @Property.State @Property.ZipCode +
+
+ +
+
+ Property Type: +

@Property.PropertyType

+
+
+ Monthly Rent: +

@Property.MonthlyRent.ToString("C")

+
+
+ +
+
+ Bedrooms: +

@Property.Bedrooms

+
+
+ Bathrooms: +

@Property.Bathrooms

+
+
+ Square Feet: +

@Property.SquareFeet.ToString("N0")

+
+
+ + @if (!string.IsNullOrEmpty(Property.Description)) + { +
+
+ Description: +

@Property.Description

+
+
+ } + + @if (ShowDates) + { +
+
+ Created: +

@Property.CreatedOn.ToString("MMMM dd, yyyy")

+
+ @if (Property.LastModifiedOn.HasValue) + { +
+ Last Modified: +

@Property.LastModifiedOn.Value.ToString("MMMM dd, yyyy")

+
+ } +
+ } +
+
+ +@code { + /// + /// Property entity to display + /// + [Parameter, EditorRequired] + public Property Property { get; set; } = default!; + + [Parameter] + public EventCallback OnEdit { get; set; } + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + /// + /// Whether to show created/modified dates + /// + [Parameter] + public bool ShowDates { get; set; } = true; + + private string GetAvailabilityBadgeClass() + { + return Property.Status switch + { + ApplicationConstants.PropertyStatuses.Available => "bg-success", + ApplicationConstants.PropertyStatuses.ApplicationPending => "bg-warning text-dark", + ApplicationConstants.PropertyStatuses.LeasePending => "bg-info", + ApplicationConstants.PropertyStatuses.Occupied => "bg-danger", + ApplicationConstants.PropertyStatuses.UnderRenovation => "bg-secondary", + ApplicationConstants.PropertyStatuses.OffMarket => "bg-dark text-white", + _ => "bg-secondary" + }; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyForm.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyForm.razor new file mode 100644 index 0000000..8c2fdbf --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyForm.razor @@ -0,0 +1,167 @@ + +@namespace Aquiis.UI.Shared.Components.Entities.Properties + + + + + @if (!string.IsNullOrEmpty(ErrorMessage)) + { + + } + +
+
+ + + +
+
+ +
+
+ + + +
+ @*
+ + + +
*@ +
+ +
+
+ + + +
+
+ + + + @foreach (var state in States.StatesArray()) + { + + } + + +
+
+ + + +
+
+ +
+
+ + + + + + + + + + + + +
+
+ + + +
+
+ +
+
+ + + + + + + + + + +
+
+ +
+
+ + + +
+
+ + + +
+
+ + + +
+
+ +
+
+ + + +
+
+ +
+
+
+ + +
+
+
+ +
+ + +
+
+@code { + + [Parameter, EditorRequired] + public PropertyFormModel Model {get; set;} = new PropertyFormModel(); + + [Parameter] + public string FormName { get; set; } = "create-property"; + + [Parameter] + public string SubmitButtonText { get; set; } = "Submit"; + + [Parameter] + public bool IsSubmitting { get; set; } = false; + + [Parameter] + public string ErrorMessage { get; set; } = string.Empty; + + [Parameter] + public EventCallback OnValidSubmit { get; set; } + + [Parameter] + public EventCallback OnCancel { get; set; } + +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyFormModel.cs b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyFormModel.cs new file mode 100644 index 0000000..c7a1075 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyFormModel.cs @@ -0,0 +1,54 @@ +using System.ComponentModel.DataAnnotations; +using Aquiis.Core.Constants; + +namespace Aquiis.UI.Shared.Components.Entities.Properties; + +/// +/// Form model for property create/edit operations +/// +public class PropertyFormModel +{ + [Required(ErrorMessage = "Address is required")] + [StringLength(200, ErrorMessage = "Address cannot exceed 200 characters")] + public string Address { get; set; } = string.Empty; + + [StringLength(50, ErrorMessage = "Unit number cannot exceed 50 characters")] + public string? UnitNumber { get; set; } + + [StringLength(100, ErrorMessage = "City cannot exceed 100 characters")] + public string City { get; set; } = string.Empty; + + [StringLength(50, ErrorMessage = "State cannot exceed 50 characters")] + public string State { get; set; } = string.Empty; + + [StringLength(20, ErrorMessage = "Zip Code cannot exceed 20 characters")] + [DataType(DataType.PostalCode)] + [RegularExpression(@"^\d{5}(-\d{4})?$", ErrorMessage = "Invalid Zip Code format.")] + public string ZipCode { get; set; } = string.Empty; + + [Required(ErrorMessage = "Property type is required")] + [StringLength(50, ErrorMessage = "Property type cannot exceed 50 characters")] + public string PropertyType { get; set; } = string.Empty; + + [Required(ErrorMessage = "Monthly rent is required")] + [Range(0.01, double.MaxValue, ErrorMessage = "Monthly rent must be greater than 0")] + public decimal MonthlyRent { get; set; } + + [Range(0, int.MaxValue, ErrorMessage = "Bedrooms cannot be negative")] + public int Bedrooms { get; set; } + + [Range(0.0, double.MaxValue, ErrorMessage = "Bathrooms cannot be negative")] + public decimal Bathrooms { get; set; } + + [Range(0, int.MaxValue, ErrorMessage = "Square feet cannot be negative")] + public int SquareFeet { get; set; } + + [StringLength(1000, ErrorMessage = "Description cannot exceed 1000 characters")] + public string Description { get; set; } = string.Empty; + + [Required(ErrorMessage = "Status is required")] + [StringLength(50, ErrorMessage = "Status cannot exceed 50 characters")] + public string Status { get; set; } = ApplicationConstants.PropertyStatuses.Available; + + public bool IsAvailable { get; set; } = true; +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyList.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyList.razor new file mode 100644 index 0000000..f95bac4 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyList.razor @@ -0,0 +1,69 @@ +
+
+
@Title
+
+
+ @if (Properties.Any()) + { +
+ @foreach (var property in Properties) + { +
+
+
+ + @property.Address + +
+ @property.City, @property.State - @property.PropertyType +
+
+ @FormatPropertyStatus(property.Status) +
+ @property.MonthlyRent.ToString("C") +
+
+ } +
+ } + else + { +

No properties found.

+ } +
+
+@code { + [Parameter] + public List Properties { get; set; } = new(); + + [Parameter] + public string Title { get; set; } = "Properties"; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public EventCallback OnViewProperty { get; set; } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + ApplicationConstants.PropertyStatuses.Available => "bg-success", + ApplicationConstants.PropertyStatuses.Occupied => "bg-primary", + //ApplicationConstants.PropertyStatuses.Maintenance => "bg-warning text-dark", + _ => "bg-secondary" + }; + } + + private string FormatPropertyStatus(string status) + { + return status switch + { + ApplicationConstants.PropertyStatuses.Available => "Available", + ApplicationConstants.PropertyStatuses.Occupied => "Occupied", + //ApplicationConstants.PropertyStatuses.Maintenance => "Under Maintenance", + _ => "Unknown" + }; + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListView.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListView.razor new file mode 100644 index 0000000..d36a091 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListView.razor @@ -0,0 +1,352 @@ +@namespace Aquiis.UI.Shared.Components.Entities.Properties +@using Aquiis.Core.Entities +@using Aquiis.Core.Constants + +
+
+
+ + +
+
+
+ +
+
+ +
+
+ +@if (ShowMetrics) +{ + +} + +@if (ViewMode == PropertyListViewMode.Grid) +{ + +
+ @foreach (var property in Properties) + { +
+ +
+ } +
+} +else +{ + +
+
+
+ + + + + + + + + + + + + + + + @foreach (var property in Properties) + { + + + + + + + + + + + + } + +
+ Address + @if (SortColumn == nameof(Property.Address)) + { + + } + + City + @if (SortColumn == nameof(Property.City)) + { + + } + + Type + @if (SortColumn == nameof(Property.PropertyType)) + { + + } + BedsBaths + Sq Ft + @if (SortColumn == nameof(Property.SquareFeet)) + { + + } + + Status + @if (SortColumn == nameof(Property.Status)) + { + + } + + Rent + @if (SortColumn == nameof(Property.MonthlyRent)) + { + + } + Actions
+ @property.Address @(!string.IsNullOrWhiteSpace(property.UnitNumber) ? $", {property.UnitNumber}" : "") +
+ @property.State @property.ZipCode +
@property.City@property.PropertyType@property.Bedrooms@property.Bathrooms@property.SquareFeet.ToString("N0") + + @FormatPropertyStatus(property.Status) + + + @property.MonthlyRent.ToString("C") + +
+ + @if (ShowEditDelete) + { + + + } +
+
+
+
+
+} + +@code { + /// + /// List of properties to display + /// + [Parameter, EditorRequired] + public List Properties { get; set; } = new(); + + /// + /// View mode (Grid or List/Table) + /// + [Parameter] + public PropertyListViewMode ViewMode { get; set; } = PropertyListViewMode.Grid; + + /// + /// Whether to show metrics cards + /// + [Parameter] + public bool ShowMetrics { get; set; } = true; + + /// + /// Whether to show edit/delete buttons + /// + [Parameter] + public bool ShowEditDelete { get; set; } = true; + + /// + /// Current search term + /// + [Parameter] + public string SearchTerm { get; set; } = string.Empty; + + /// + /// Current status filter + /// + [Parameter] + public string StatusFilter { get; set; } = string.Empty; + + /// + /// Current sort column + /// + [Parameter] + public string SortColumn { get; set; } = nameof(Property.Address); + + /// + /// Sort direction + /// + [Parameter] + public bool SortAscending { get; set; } = true; + + /// + /// Total properties count (for metrics) + /// + [Parameter] + public int TotalCount { get; set; } + + /// + /// Available properties count (for metrics) + /// + [Parameter] + public int AvailableCount { get; set; } + + /// + /// Pending properties count (for metrics) + /// + [Parameter] + public int PendingCount { get; set; } + + /// + /// Occupied properties count (for metrics) + /// + [Parameter] + public int OccupiedCount { get; set; } + + /// + /// Total monthly rent (for metrics) + /// + [Parameter] + public decimal TotalMonthlyRent { get; set; } + + /// + /// Callback when search term changes + /// + [Parameter] + public EventCallback OnSearchChanged { get; set; } + + /// + /// Callback when status filter changes + /// + [Parameter] + public EventCallback OnStatusFilterChanged { get; set; } + + /// + /// Callback when filters are cleared + /// + [Parameter] + public EventCallback OnClearFilters { get; set; } + + /// + /// Callback when sort is requested + /// + [Parameter] + public EventCallback<(string Column, bool Ascending)> OnSort { get; set; } + + /// + /// Callback when View button is clicked + /// + [Parameter] + public EventCallback OnView { get; set; } + + /// + /// Callback when Edit button is clicked + /// + [Parameter] + public EventCallback OnEdit { get; set; } + + /// + /// Callback when Delete button is clicked + /// + [Parameter] + public EventCallback OnDelete { get; set; } + + private async Task HandleSearchChanged(ChangeEventArgs e) + { + await OnSearchChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleStatusFilterChanged(ChangeEventArgs e) + { + await OnStatusFilterChanged.InvokeAsync(e.Value?.ToString() ?? string.Empty); + } + + private async Task HandleSort(string column) + { + var ascending = SortColumn == column ? !SortAscending : true; + await OnSort.InvokeAsync((column, ascending)); + } + + private async Task HandleView(Guid propertyId) + { + await OnView.InvokeAsync(propertyId); + } + + private async Task HandleEdit(Guid propertyId) + { + await OnEdit.InvokeAsync(propertyId); + } + + private async Task HandleDelete(Guid propertyId) + { + await OnDelete.InvokeAsync(propertyId); + } + + private string GetStatusBadgeClass(string status) + { + return status switch + { + var s when s == ApplicationConstants.PropertyStatuses.Available => "bg-success", + var s when s == ApplicationConstants.PropertyStatuses.ApplicationPending => "bg-info", + var s when s == ApplicationConstants.PropertyStatuses.LeasePending => "bg-warning", + var s when s == ApplicationConstants.PropertyStatuses.Occupied => "bg-danger", + var s when s == ApplicationConstants.PropertyStatuses.UnderRenovation => "bg-secondary", + var s when s == ApplicationConstants.PropertyStatuses.OffMarket => "bg-dark", + _ => "bg-secondary" + }; + } + + private string FormatPropertyStatus(string status) + { + return status switch + { + var s when s == ApplicationConstants.PropertyStatuses.ApplicationPending => "Application Pending", + var s when s == ApplicationConstants.PropertyStatuses.LeasePending => "Lease Pending", + var s when s == ApplicationConstants.PropertyStatuses.UnderRenovation => "Under Renovation", + var s when s == ApplicationConstants.PropertyStatuses.OffMarket => "Off Market", + _ => status + }; + } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListViewMode.cs b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListViewMode.cs new file mode 100644 index 0000000..bf96091 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyListViewMode.cs @@ -0,0 +1,17 @@ +namespace Aquiis.UI.Shared.Components.Entities.Properties; + +/// +/// Defines the display mode for property list views +/// +public enum PropertyListViewMode +{ + /// + /// Display properties in a grid of cards + /// + Grid, + + /// + /// Display properties in a table/list format + /// + Table +} diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyMetricsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyMetricsCard.razor new file mode 100644 index 0000000..6acfc4b --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyMetricsCard.razor @@ -0,0 +1,119 @@ +@using Aquiis.UI.Shared.Components.Common +
+ @if(ShowTotalProperties){ + + } + @if(ShowAvailableProperties){ + + + } + @if(ShowOccupiedProperties){ + + } + @if(ShowLeasePendingProperties){ + + } + + @if(ShowActiveLeases){ + + } + + @if(ShowTotalTenants){ + + } + + @if(ShowActiveTenants){ + + } + + @if(ShowOccupancyRate){ + + } + + @if(ShowTotalMonthlyRent){ + + } +
+ +@code { + [Parameter] + public bool ShowTotalProperties { get; set; } = true; + + [Parameter] + public bool ShowAvailableProperties { get; set; } = false; + + [Parameter] + public bool ShowLeasePendingProperties { get; set; } = false; + + [Parameter] + public bool ShowOccupiedProperties { get; set; } = false; + + [Parameter] + public bool ShowTotalMonthlyRent { get; set; } = false; + + [Parameter] + public bool ShowActiveTenants { get; set; } = false; + + [Parameter] + public bool ShowTotalTenants { get; set; } = false; + + [Parameter] + public bool ShowActiveLeases { get; set; } = false; + + [Parameter] + public bool ShowOccupancyRate { get; set; } = false; + + [Parameter] + public int TotalPropertiesCount { get; set; } + + [Parameter] + public int ActiveTenantsCount { get; set; } + + [Parameter] + public int TotalTenantCount { get; set; } + + [Parameter] + public int ActiveLeasesCount { get; set; } + + [Parameter] + public int AvailableCount { get; set; } + + [Parameter] + public int PendingCount { get; set; } + + [Parameter] + public int OccupiedCount { get; set; } + + [Parameter] + public decimal TotalMonthlyRent { get; set; } + + [Parameter] + public decimal OccupancyRate { get; set; } +} \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyOccupancyMetricsCard.razor b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyOccupancyMetricsCard.razor new file mode 100644 index 0000000..e5490a4 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Properties/PropertyOccupancyMetricsCard.razor @@ -0,0 +1,70 @@ +
+
+ @if(ShowAvailable){ +
+
+
+
Available
+

@AvailableCount

+
+
+
+ } + @if(ShowPending){ +
+
+
+
Pending Lease
+

@PendingCount

+
+
+
+ } + @if(ShowOccupied){ +
+
+
+
Occupied
+

@OccupiedCount

+
+
+
+ } + @if(ShowMonthlyRent){ +
+
+
+
Total Rent/Month
+

@TotalMonthlyRent.ToString("C")

+
+
+
+ } +
+
+ + @code { + [Parameter] + public bool ShowAvailable { get; set; } = true; + + [Parameter] + public bool ShowPending { get; set; } = true; + + [Parameter] + public bool ShowOccupied { get; set; } = true; + + [Parameter] + public bool ShowMonthlyRent { get; set; } = true; + + [Parameter] + public int AvailableCount { get; set; } + + [Parameter] + public int PendingCount { get; set; } + + [Parameter] + public int OccupiedCount { get; set; } + + [Parameter] + public decimal TotalMonthlyRent { get; set; } + } \ No newline at end of file diff --git a/3-Aquiis.UI.Shared/Components/Entities/Repairs/RepairList.razor b/3-Aquiis.UI.Shared/Components/Entities/Repairs/RepairList.razor new file mode 100644 index 0000000..9e4a7d0 --- /dev/null +++ b/3-Aquiis.UI.Shared/Components/Entities/Repairs/RepairList.razor @@ -0,0 +1,171 @@ +
+
+
+ @Title +
+
+ + + @if (ShowAddButton && OnAddRepair.HasDelegate) + { + + } +
+
+
+ @if (Repairs == null) + { +
+
+ Loading... +
+
+ } + else if (!Repairs.Any()) + { +

No repairs recorded for this property.

+ } + else + { +
+ @foreach (var repair in Repairs.OrderByDescending(r => r.CompletedOn ?? r.CreatedOn)) + { +
+
+
+
+ @if (ShowLinks && OnViewRepair.HasDelegate) + { + + @repair.Description + + } + else + { + @repair.Description + } +
+
+ + @repair.RepairType + @if (!string.IsNullOrEmpty(repair.ContractorName)) + { + @repair.ContractorName + } + +
+ @if (!string.IsNullOrEmpty(repair.PartsReplaced)) + { + + Parts: @repair.PartsReplaced + + } +
+
+ @if (repair.CompletedOn.HasValue) + { + Completed +
+ @repair.CompletedOn.Value.ToString("MMM dd, yyyy") + } + else + { + In Progress +
+ Started @repair.CreatedOn.ToString("MMM dd, yyyy") + } + @if (repair.Cost > 0) + { +
+ @repair.Cost.ToString("C") +
+ } +
+
+ @if (repair.DurationMinutes > 0 || repair.WarrantyApplies) + { +
+ + @if (repair.DurationMinutes > 0) + { + + Duration: @FormatDuration(repair.DurationMinutes) + + } + @if (repair.WarrantyApplies && repair.WarrantyExpiresOn.HasValue) + { + + Warranty until @repair.WarrantyExpiresOn.Value.ToString("MMM dd, yyyy") + + } + +
+ } +
+ } +
+ + @if (ShowTotalCost) + { + + } + } +
+
+ +@code { + [Parameter] + public List? Repairs { get; set; } + + [Parameter] + public string Title { get; set; } = "Repairs"; + + [Parameter] + public string HeaderCssClass { get; set; } = ""; + + [Parameter] + public bool ShowAddButton { get; set; } = true; + + [Parameter] + public bool ShowLinks { get; set; } = true; + + [Parameter] + public bool ShowTotalCost { get; set; } = true; + + [Parameter] + public EventCallback OnAddRepair { get; set; } + + [Parameter] + public EventCallback OnViewRepair { get; set; } + + [Parameter] + public EventCallback OnViewAllRepairs { get; set; } + + private string FormatDuration(int minutes) + { + if (minutes < 60) + return $"{minutes} min"; + + var hours = minutes / 60; + var remainingMinutes = minutes % 60; + + if (remainingMinutes == 0) + return $"{hours} hr"; + + return $"{hours} hr {remainingMinutes} min"; + } +} diff --git a/3-Aquiis.UI.Shared/Components/Layout/SharedMainLayout.razor b/3-Aquiis.UI.Shared/Components/Layout/SharedMainLayout.razor index 039975d..411ab22 100644 --- a/3-Aquiis.UI.Shared/Components/Layout/SharedMainLayout.razor +++ b/3-Aquiis.UI.Shared/Components/Layout/SharedMainLayout.razor @@ -1,14 +1,15 @@ @inherits LayoutComponentBase @namespace Aquiis.UI.Shared.Components.Layout @using Microsoft.AspNetCore.Components.Authorization +@using Microsoft.EntityFrameworkCore.Metadata.Internal -
-