Files
jobtrackingapp/JobTrackerApi/Migrations/JobTrackerContextModelSnapshot.cs
T
cesnimda eac34705e3 feat: Phase 0 foundation — Job entity, expanded pipeline, AI service lockdown, DateApplied history
Unblocks the documented core workflow and closes the AI-service exposure,
without changing existing behaviour.

Job/JobApplication split (additive; see ADR-002):
- New Job entity (the opportunity) with owner-scoped query filter; nullable
  JobApplication.JobId FK. Nothing reads Job yet.
- Migration AddJobEntityAndProspectStages, hand-edited to drop reconciler-owned
  tables the scaffolder re-emitted; verified against the real dev DB.

Pipeline: 10 internal stages across three concerns kept separate —
PipelineStage (workflow) / PipelineGroup (UI: NotApplied/Active/Closed) /
PipelineCategory (analytics). Adds Saved/Interested/Preparing/Withdrawn;
keeps Waiting and Ghosted. Kanban shows 3 grouped columns; cards keep a stage
chip and full transitions; drag applies only safe transitions (never infers
Ghosted/Withdrawn).

DateApplied nullable + SavedAt. Cleared when leaving Applied so analytics stay
accurate; the discarded date is preserved as an AppliedDateCleared JobEvent.

AI service lockdown: no host port; private ai_internal network (backend is the
only other member); X-Ai-Service-Token required on all non-/health endpoints;
AI_SERVICE_TOKEN mandatory via compose. Verified backend-only against the live
stack.

Also carries two pre-existing working-tree files (views/ProfilePage.tsx,
views/CareerWorkspacePage.tsx) so the tree is clean for the branch integration.

Tests: +40 backend (247 total), +5 sidecar (16), +15 frontend.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 17:05:25 +02:00

1385 lines
47 KiB
C#

// <auto-generated />
using System;
using JobTrackerApi.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace JobTrackerApi.Migrations
{
[DbContext(typeof(JobTrackerContext))]
partial class JobTrackerContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.14");
modelBuilder.Entity("JobTrackerApi.Models.ApplicationUser", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<int>("AccessFailedCount")
.HasColumnType("INTEGER");
b.Property<string>("AvatarImageDataUrl")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<int?>("CurrentCvExtractionRunId")
.HasColumnType("INTEGER");
b.Property<int?>("CurrentCvProfileVersion")
.HasColumnType("INTEGER");
b.Property<int?>("CurrentCvUploadArtifactId")
.HasColumnType("INTEGER");
b.Property<string>("DisplayName")
.HasColumnType("TEXT");
b.Property<string>("Email")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<bool>("EmailConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("FirstName")
.HasColumnType("TEXT");
b.Property<string>("GoogleEmail")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("GoogleLinkedAt")
.HasColumnType("TEXT");
b.Property<string>("GoogleSubject")
.HasColumnType("TEXT");
b.Property<string>("LastName")
.HasColumnType("TEXT");
b.Property<bool>("LockoutEnabled")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("TEXT");
b.Property<string>("MicrosoftEmail")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("MicrosoftLinkedAt")
.HasColumnType("TEXT");
b.Property<string>("MicrosoftSubject")
.HasColumnType("TEXT");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedUserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("PasswordHash")
.HasColumnType("TEXT");
b.Property<string>("PhoneNumber")
.HasColumnType("TEXT");
b.Property<bool>("PhoneNumberConfirmed")
.HasColumnType("INTEGER");
b.Property<string>("ProfileCvStructureJson")
.HasColumnType("TEXT");
b.Property<string>("ProfileCvText")
.HasColumnType("TEXT");
b.Property<string>("SecurityStamp")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("TotpEnabledAtUtc")
.HasColumnType("TEXT");
b.Property<string>("TotpPendingSecretEncrypted")
.HasColumnType("TEXT");
b.Property<string>("TotpSecretEncrypted")
.HasColumnType("TEXT");
b.Property<bool>("TwoFactorEnabled")
.HasColumnType("INTEGER");
b.Property<string>("UserName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasDatabaseName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
});
modelBuilder.Entity("JobTrackerApi.Models.Attachment", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("FileName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("FilePath")
.IsRequired()
.HasColumnType("TEXT");
b.Property<long>("FileSize")
.HasColumnType("INTEGER");
b.Property<string>("FileType")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("JobApplicationId")
.HasColumnType("INTEGER");
b.Property<string>("Purpose")
.HasColumnType("TEXT");
b.Property<DateTime>("UploadDate")
.HasColumnType("TEXT");
b.Property<bool>("UseForAi")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.HasIndex("JobApplicationId");
b.ToTable("Attachments");
});
modelBuilder.Entity("JobTrackerApi.Models.Company", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime?>("LastContactedAt")
.HasColumnType("TEXT");
b.Property<string>("Location")
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime?>("NextContactAt")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.HasColumnType("TEXT");
b.Property<string>("PipelineStage")
.HasColumnType("TEXT");
b.Property<string>("RecruiterEmail")
.HasColumnType("TEXT");
b.Property<string>("RecruiterLinkedIn")
.HasColumnType("TEXT");
b.Property<string>("RecruiterName")
.HasColumnType("TEXT");
b.Property<string>("Source")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OwnerUserId");
b.ToTable("Companies");
});
modelBuilder.Entity("JobTrackerApi.Models.Correspondence", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("AttachmentMetadataJson")
.HasColumnType("TEXT");
b.Property<string>("Channel")
.HasColumnType("TEXT");
b.Property<string>("Content")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTime>("Date")
.HasColumnType("TEXT");
b.Property<string>("Direction")
.HasColumnType("TEXT");
b.Property<string>("ExternalFrom")
.HasColumnType("TEXT");
b.Property<string>("ExternalLabelsJson")
.HasColumnType("TEXT");
b.Property<string>("ExternalMessageId")
.HasColumnType("TEXT");
b.Property<string>("ExternalThreadId")
.HasColumnType("TEXT");
b.Property<string>("ExternalTo")
.HasColumnType("TEXT");
b.Property<string>("From")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("JobApplicationId")
.HasColumnType("INTEGER");
b.Property<string>("Provider")
.HasColumnType("TEXT");
b.Property<string>("Subject")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("JobApplicationId");
b.ToTable("Correspondences");
});
modelBuilder.Entity("JobTrackerApi.Models.CvExtractionRun", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("AppliedAtUtc")
.HasColumnType("TEXT");
b.Property<int?>("ArtifactId")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("CompletedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("ErrorMessage")
.HasColumnType("TEXT");
b.Property<string>("LlmPromptVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("NormalizedText")
.HasColumnType("TEXT");
b.Property<string>("NormalizerVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ParserVersion")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("RawExtractedText")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("StartedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("StructuredProfileJson")
.HasColumnType("TEXT");
b.Property<string>("Trigger")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("ArtifactId");
b.HasIndex("OwnerUserId", "StartedAtUtc");
b.ToTable("CvExtractionRuns");
});
modelBuilder.Entity("JobTrackerApi.Models.CvUploadArtifact", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<long>("ByteSize")
.HasColumnType("INTEGER");
b.Property<string>("MimeType")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OriginalFileName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Sha256")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("StoragePath")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("StoredFileName")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("UploadedAtUtc")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OwnerUserId", "UploadedAtUtc");
b.ToTable("CvUploadArtifacts");
});
modelBuilder.Entity("JobTrackerApi.Models.GmailConnection", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("AccessTokenExpiresAt")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ConnectedAt")
.HasColumnType("TEXT");
b.Property<string>("EncryptedAccessToken")
.HasColumnType("TEXT");
b.Property<string>("EncryptedRefreshToken")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("GmailAddress")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncAttemptedAt")
.HasColumnType("TEXT");
b.Property<string>("LastSyncError")
.HasColumnType("TEXT");
b.Property<string>("LastSyncMode")
.HasColumnType("TEXT");
b.Property<string>("LastSyncSource")
.HasColumnType("TEXT");
b.Property<string>("LastSyncStatus")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncSucceededAt")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncedAt")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Scope")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("OwnerUserId");
b.HasIndex("OwnerUserId", "GmailAddress")
.IsUnique();
b.ToTable("GmailConnections");
});
modelBuilder.Entity("JobTrackerApi.Models.GmailReviewDecision", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("Decision")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int?>("JobApplicationId")
.HasColumnType("INTEGER");
b.Property<string>("Note")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("ThreadId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("UpdatedAt")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("GmailReviewDecisions");
});
modelBuilder.Entity("JobTrackerApi.Models.ImapConnection", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("ConnectedAt")
.HasColumnType("TEXT");
b.Property<string>("EncryptedPassword")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Host")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncAttemptedAt")
.HasColumnType("TEXT");
b.Property<string>("LastSyncError")
.HasColumnType("TEXT");
b.Property<string>("LastSyncMode")
.HasColumnType("TEXT");
b.Property<string>("LastSyncSource")
.HasColumnType("TEXT");
b.Property<string>("LastSyncStatus")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncSucceededAt")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncedAt")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Port")
.HasColumnType("INTEGER");
b.Property<bool>("UseSsl")
.HasColumnType("INTEGER");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("ImapConnections");
});
modelBuilder.Entity("JobTrackerApi.Models.Job", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("CompanyId")
.HasColumnType("INTEGER");
b.Property<string>("CountryCode")
.HasColumnType("TEXT");
b.Property<DateTime?>("Deadline")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("DescriptionLanguage")
.HasColumnType("TEXT");
b.Property<string>("JobTitle")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("JobUrl")
.HasColumnType("TEXT");
b.Property<string>("Location")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.HasColumnType("TEXT");
b.Property<string>("Salary")
.HasColumnType("TEXT");
b.Property<string>("SalaryCurrency")
.HasColumnType("TEXT");
b.Property<decimal?>("SalaryMax")
.HasColumnType("TEXT");
b.Property<decimal?>("SalaryMin")
.HasColumnType("TEXT");
b.Property<string>("SalaryPeriod")
.HasColumnType("TEXT");
b.Property<DateTime>("SavedAt")
.HasColumnType("TEXT");
b.Property<string>("ShortSummary")
.HasColumnType("TEXT");
b.Property<string>("Source")
.HasColumnType("TEXT");
b.Property<string>("Tags")
.HasColumnType("TEXT");
b.Property<string>("TranslatedDescription")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("CompanyId");
b.HasIndex("OwnerUserId");
b.ToTable("Jobs");
});
modelBuilder.Entity("JobTrackerApi.Models.JobApplication", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("CompanyId")
.HasColumnType("INTEGER");
b.Property<string>("CoverLetterText")
.HasColumnType("TEXT");
b.Property<DateTime?>("DateApplied")
.HasColumnType("TEXT");
b.Property<DateTime?>("Deadline")
.HasColumnType("TEXT");
b.Property<DateTime?>("DeletedAt")
.HasColumnType("TEXT");
b.Property<string>("Description")
.HasColumnType("TEXT");
b.Property<string>("DescriptionLanguage")
.HasColumnType("TEXT");
b.Property<DateTime?>("FeedbackRequestedAt")
.HasColumnType("TEXT");
b.Property<DateTime?>("FollowUpAt")
.HasColumnType("TEXT");
b.Property<bool>("HasCoverLetter")
.HasColumnType("INTEGER");
b.Property<bool>("HasOtherAttachment")
.HasColumnType("INTEGER");
b.Property<bool>("HasPortfolio")
.HasColumnType("INTEGER");
b.Property<bool>("HasResume")
.HasColumnType("INTEGER");
b.Property<bool>("IsDeleted")
.HasColumnType("INTEGER");
b.Property<int?>("JobId")
.HasColumnType("INTEGER");
b.Property<string>("JobTitle")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("JobUrl")
.HasColumnType("TEXT");
b.Property<DateTime?>("LastReminderEmailSentAt")
.HasColumnType("TEXT");
b.Property<string>("Location")
.HasColumnType("TEXT");
b.Property<string>("NextAction")
.HasColumnType("TEXT");
b.Property<string>("Notes")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.HasColumnType("TEXT");
b.Property<string>("RecruiterMessageDraft")
.HasColumnType("TEXT");
b.Property<DateTime?>("ResponseDate")
.HasColumnType("TEXT");
b.Property<bool>("ResponseReceived")
.HasColumnType("INTEGER");
b.Property<string>("Salary")
.HasColumnType("TEXT");
b.Property<string>("SalaryCurrency")
.HasColumnType("TEXT");
b.Property<decimal?>("SalaryMax")
.HasColumnType("TEXT");
b.Property<decimal?>("SalaryMin")
.HasColumnType("TEXT");
b.Property<string>("SalaryPeriod")
.HasColumnType("TEXT");
b.Property<DateTime>("SavedAt")
.HasColumnType("TEXT");
b.Property<string>("ShortSummary")
.HasColumnType("TEXT");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Tags")
.HasColumnType("TEXT");
b.Property<string>("TailoredCvText")
.HasColumnType("TEXT");
b.Property<DateTime?>("TailoredCvUpdatedAt")
.HasColumnType("TEXT");
b.Property<string>("TranslatedDescription")
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("CompanyId");
b.HasIndex("JobId");
b.HasIndex("OwnerUserId");
b.HasIndex("OwnerUserId", "FollowUpAt");
b.HasIndex("OwnerUserId", "IsDeleted");
b.HasIndex("OwnerUserId", "IsDeleted", "Status");
b.ToTable("JobApplications");
});
modelBuilder.Entity("JobTrackerApi.Models.JobEvent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTime>("At")
.HasColumnType("TEXT");
b.Property<int>("JobApplicationId")
.HasColumnType("INTEGER");
b.Property<string>("NewValue")
.HasColumnType("TEXT");
b.Property<string>("Note")
.HasColumnType("TEXT");
b.Property<string>("OldValue")
.HasColumnType("TEXT");
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("JobApplicationId");
b.ToTable("JobEvents");
});
modelBuilder.Entity("JobTrackerApi.Models.MicrosoftGraphConnection", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("AccessTokenExpiresAt")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ConnectedAt")
.HasColumnType("TEXT");
b.Property<string>("EncryptedAccessToken")
.HasColumnType("TEXT");
b.Property<string>("EncryptedRefreshToken")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncAttemptedAt")
.HasColumnType("TEXT");
b.Property<string>("LastSyncError")
.HasColumnType("TEXT");
b.Property<string>("LastSyncMode")
.HasColumnType("TEXT");
b.Property<string>("LastSyncSource")
.HasColumnType("TEXT");
b.Property<string>("LastSyncStatus")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncSucceededAt")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastSyncedAt")
.HasColumnType("TEXT");
b.Property<string>("MailAddress")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Scope")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("MicrosoftGraphConnections");
});
modelBuilder.Entity("JobTrackerApi.Models.RuleSettings", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("AppliedFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("AppliedGhostDays")
.HasColumnType("INTEGER");
b.Property<int>("FeedbackFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("FeedbackGhostDays")
.HasColumnType("INTEGER");
b.Property<int>("OfferFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("OfferGhostDays")
.HasColumnType("INTEGER");
b.HasKey("Id");
b.ToTable("RuleSettings");
b.HasData(
new
{
Id = 1,
AppliedFollowUpDays = 14,
AppliedGhostDays = 30,
FeedbackFollowUpDays = 7,
FeedbackGhostDays = 14,
OfferFollowUpDays = 7,
OfferGhostDays = 14
});
});
modelBuilder.Entity("JobTrackerApi.Models.SystemEmailSettings", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<bool?>("Enabled")
.HasColumnType("INTEGER");
b.Property<string>("From")
.HasColumnType("TEXT");
b.Property<string>("FromName")
.HasColumnType("TEXT");
b.Property<bool?>("SmtpEnableSsl")
.HasColumnType("INTEGER");
b.Property<string>("SmtpHost")
.HasColumnType("TEXT");
b.Property<string>("SmtpPassword")
.HasColumnType("TEXT");
b.Property<int?>("SmtpPort")
.HasColumnType("INTEGER");
b.Property<int?>("SmtpTimeoutMs")
.HasColumnType("INTEGER");
b.Property<string>("SmtpUser")
.HasColumnType("TEXT");
b.HasKey("Id");
b.ToTable("SystemEmailSettings");
});
modelBuilder.Entity("JobTrackerApi.Models.TailoredCvDraft", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int?>("CanonicalProfileVersion")
.HasColumnType("INTEGER");
b.Property<string>("CustomSectionsJson")
.HasColumnType("TEXT");
b.Property<string>("EducationJson")
.HasColumnType("TEXT");
b.Property<string>("ExperienceJson")
.HasColumnType("TEXT");
b.Property<string>("GenerationContextHash")
.HasColumnType("TEXT");
b.Property<string>("Headline")
.HasColumnType("TEXT");
b.Property<int>("JobApplicationId")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset?>("LastEditedAtUtc")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("LastGeneratedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("OwnerUserId")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("RenderOptionsJson")
.HasColumnType("TEXT");
b.Property<string>("SelectedSkillsJson")
.HasColumnType("TEXT");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SummaryJson")
.HasColumnType("TEXT");
b.Property<string>("TemplateId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("JobApplicationId")
.IsUnique();
b.HasIndex("OwnerUserId", "JobApplicationId")
.IsUnique();
b.ToTable("TailoredCvDrafts");
});
modelBuilder.Entity("JobTrackerApi.Models.TrustedDevice", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("DeviceLabel")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ExpiresAtUtc")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("LastSeenAtUtc")
.HasColumnType("TEXT");
b.Property<string>("TokenHash")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("TokenHash");
b.HasIndex("UserId");
b.ToTable("TrustedDevices");
});
modelBuilder.Entity("JobTrackerApi.Models.TwoFactorRecoveryCode", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("CodeHash")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("UsedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId", "UsedAtUtc");
b.ToTable("TwoFactorRecoveryCodes");
});
modelBuilder.Entity("JobTrackerApi.Models.UserRuleSettings", b =>
{
b.Property<string>("OwnerUserId")
.HasColumnType("TEXT");
b.Property<int>("AppliedFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("AppliedGhostDays")
.HasColumnType("INTEGER");
b.Property<int>("FeedbackFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("FeedbackGhostDays")
.HasColumnType("INTEGER");
b.Property<int>("OfferFollowUpDays")
.HasColumnType("INTEGER");
b.Property<int>("OfferGhostDays")
.HasColumnType("INTEGER");
b.HasKey("OwnerUserId");
b.ToTable("UserRuleSettings");
});
modelBuilder.Entity("JobTrackerApi.Models.UserSession", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("CreatedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("DeviceLabel")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ExpiresAtUtc")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("LastSeenAtUtc")
.HasColumnType("TEXT");
b.Property<DateTimeOffset?>("RevokedAtUtc")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("UserSessions");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.HasColumnType("TEXT");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.Property<string>("NormalizedName")
.HasMaxLength(256)
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<string>("ClaimType")
.HasColumnType("TEXT");
b.Property<string>("ClaimValue")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("ProviderKey")
.HasColumnType("TEXT");
b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("RoleId")
.HasColumnType("TEXT");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("TEXT");
b.Property<string>("LoginProvider")
.HasColumnType("TEXT");
b.Property<string>("Name")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("JobTrackerApi.Models.Attachment", b =>
{
b.HasOne("JobTrackerApi.Models.JobApplication", "JobApplication")
.WithMany("Attachments")
.HasForeignKey("JobApplicationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("JobApplication");
});
modelBuilder.Entity("JobTrackerApi.Models.Correspondence", b =>
{
b.HasOne("JobTrackerApi.Models.JobApplication", "JobApplication")
.WithMany("Messages")
.HasForeignKey("JobApplicationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("JobApplication");
});
modelBuilder.Entity("JobTrackerApi.Models.CvExtractionRun", b =>
{
b.HasOne("JobTrackerApi.Models.CvUploadArtifact", "Artifact")
.WithMany()
.HasForeignKey("ArtifactId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("Artifact");
});
modelBuilder.Entity("JobTrackerApi.Models.Job", b =>
{
b.HasOne("JobTrackerApi.Models.Company", "Company")
.WithMany()
.HasForeignKey("CompanyId")
.OnDelete(DeleteBehavior.Restrict)
.IsRequired();
b.Navigation("Company");
});
modelBuilder.Entity("JobTrackerApi.Models.JobApplication", b =>
{
b.HasOne("JobTrackerApi.Models.Company", "Company")
.WithMany("Jobs")
.HasForeignKey("CompanyId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("JobTrackerApi.Models.Job", "Job")
.WithMany("Applications")
.HasForeignKey("JobId")
.OnDelete(DeleteBehavior.SetNull);
b.Navigation("Company");
b.Navigation("Job");
});
modelBuilder.Entity("JobTrackerApi.Models.JobEvent", b =>
{
b.HasOne("JobTrackerApi.Models.JobApplication", "JobApplication")
.WithMany("Events")
.HasForeignKey("JobApplicationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("JobApplication");
});
modelBuilder.Entity("JobTrackerApi.Models.TailoredCvDraft", b =>
{
b.HasOne("JobTrackerApi.Models.JobApplication", "JobApplication")
.WithOne("TailoredCvDraft")
.HasForeignKey("JobTrackerApi.Models.TailoredCvDraft", "JobApplicationId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("JobApplication");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("JobTrackerApi.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("JobTrackerApi.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("JobTrackerApi.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("JobTrackerApi.Models.ApplicationUser", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("JobTrackerApi.Models.Company", b =>
{
b.Navigation("Jobs");
});
modelBuilder.Entity("JobTrackerApi.Models.Job", b =>
{
b.Navigation("Applications");
});
modelBuilder.Entity("JobTrackerApi.Models.JobApplication", b =>
{
b.Navigation("Attachments");
b.Navigation("Events");
b.Navigation("Messages");
b.Navigation("TailoredCvDraft");
});
#pragma warning restore 612, 618
}
}
}