8aae30765f
Setup Wizard: reduced from 10 steps to 5 (Company Info → QB Migration →
Pricing Defaults → Named Ovens → Notifications). Removed Doc Numbering,
Job Settings, Payment Terms, Pricing Tiers, and Team Members steps — these
all have sensible defaults and are accessible any time in Company Settings.
Wizard now completes in ~5 minutes instead of 15–20.
Dashboard progress widget (new): "Get the most out of your shop" checklist
appears for Company Admins after wizard completion. Tracks six post-setup
activation tasks with dynamic progress badge, motivating subtitle copy,
collapsed-state persistence via localStorage, and a full completion state
("Your shop is fully set up 🎉") that replaces the checklist at 100%.
The next recommended step is highlighted with a solid CTA button and a
subtle blue row tint. Completed steps show encouraging green subtext instead
of just "Done". Widget disappears from controller when AllDone would have
caused a silent vanish — now renders the completion state instead.
Guided activation (Daily Board): rewrote the BoardIntroStep callout to lead
with "This is your shop in real time" and a plain-English description of the
board's purpose. Added a separate InstructionText field to
GuidedActivationCalloutViewModel so the "Move this job to the next stage"
action prompt renders as a distinct bold line with an arrow icon rather than
being buried in the body copy. After the stage change, the confirmation
callout now reads "Nice — your workflow just updated" to reinforce what just
happened before prompting the invoice step.
All copy passes the "shop owner, not SaaS" test: no technical jargon,
benefit-driven descriptions, natural language throughout.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
132 lines
5.3 KiB
C#
132 lines
5.3 KiB
C#
namespace PowderCoating.Shared.Constants;
|
|
|
|
public static class AppConstants
|
|
{
|
|
public const string ApplicationName = "Powder Coating Management System";
|
|
public const string Version = "1.0.0";
|
|
|
|
/// <summary>Set to true to enable SMS features throughout the UI.</summary>
|
|
public const bool SmsEnabled = false;
|
|
|
|
public static class Roles
|
|
{
|
|
// System-level roles
|
|
public const string SuperAdmin = "SuperAdmin"; // Platform administrator
|
|
|
|
// Legacy company-level roles (deprecated - use CompanyRole field instead)
|
|
public const string Administrator = "Administrator";
|
|
public const string Manager = "Manager";
|
|
public const string Employee = "Employee";
|
|
public const string ShopFloor = "ShopFloor";
|
|
public const string ReadOnly = "ReadOnly";
|
|
}
|
|
|
|
public static class CompanyRoles
|
|
{
|
|
public const string CompanyAdmin = "CompanyAdmin";
|
|
public const string Manager = "Manager";
|
|
public const string Worker = "Worker";
|
|
public const string Viewer = "Viewer";
|
|
}
|
|
|
|
public static class Policies
|
|
{
|
|
// System-level policies
|
|
public const string SuperAdminOnly = "SuperAdminOnly";
|
|
public const string CompanyAdminOnly = "CompanyAdminOnly";
|
|
public const string CanManageUsers = "CanManageUsers";
|
|
public const string CanViewData = "CanViewData";
|
|
|
|
// Permission-based policies
|
|
public const string CanManageJobs = "CanManageJobs";
|
|
public const string CanManageInventory = "CanManageInventory";
|
|
public const string CanManageCustomers = "CanManageCustomers";
|
|
public const string CanCreateQuotes = "CanCreateQuotes";
|
|
public const string CanManageCalendar = "CanManageCalendar";
|
|
public const string CanViewCalendar = "CanViewCalendar";
|
|
public const string CanManageProducts = "CanManageProducts";
|
|
public const string CanViewProducts = "CanViewProducts";
|
|
public const string CanManageEquipment = "CanManageEquipment";
|
|
public const string CanManageVendors = "CanManageVendors";
|
|
public const string CanManagePurchaseOrders = "CanManagePurchaseOrders";
|
|
public const string CanManageMaintenance = "CanManageMaintenance";
|
|
public const string CanManageInvoices = "CanManageInvoices";
|
|
public const string CanViewReports = "CanViewReports";
|
|
}
|
|
|
|
public static class FileUpload
|
|
{
|
|
public const long MaxFileSize = 10 * 1024 * 1024; // 10 MB
|
|
public static readonly string[] AllowedImageExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".webp" };
|
|
public static readonly string[] AllowedDocumentExtensions = { ".pdf", ".doc", ".docx", ".xls", ".xlsx" };
|
|
}
|
|
|
|
public static class Pagination
|
|
{
|
|
public const int DefaultPageSize = 25;
|
|
public const int MaxPageSize = 100;
|
|
}
|
|
|
|
public static class SubscriptionConstants
|
|
{
|
|
public const int GracePeriodDays = 14;
|
|
public const int UnlimitedValue = -1;
|
|
}
|
|
|
|
public static class RateLimitPolicies
|
|
{
|
|
public const string Auth = "rl_auth";
|
|
public const string Registration = "rl_registration";
|
|
public const string Public = "rl_public";
|
|
public const string Webhook = "rl_webhook";
|
|
public const string Ai = "rl_ai";
|
|
public const string Authenticated = "rl_authenticated";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Canonical feature identifiers written to AiUsageLog.Feature.
|
|
/// Keep these in sync with any UI display labels in AiUsageReport.
|
|
/// </summary>
|
|
public static class AiFeatures
|
|
{
|
|
public const string PhotoQuote = "PhotoQuote";
|
|
public const string HelpChat = "HelpChat";
|
|
public const string ReceiptScan = "ReceiptScan";
|
|
public const string AccountSuggest = "AccountSuggest";
|
|
public const string ArFollowUp = "ArFollowUp";
|
|
public const string FinancialSummary = "FinancialSummary";
|
|
public const string CashFlowForecast = "CashFlowForecast";
|
|
public const string AnomalyDetection = "AnomalyDetection";
|
|
}
|
|
|
|
public static class Legal
|
|
{
|
|
/// <summary>
|
|
/// Bump this string whenever the Terms of Service content changes.
|
|
/// The new value will be recorded on all future acceptances.
|
|
/// Format: YYYY-MM-DD of the effective date.
|
|
/// </summary>
|
|
public const string CurrentTosVersion = "2026-04-09";
|
|
}
|
|
|
|
public static class GuidedActivation
|
|
{
|
|
public const string QuoteFirstPath = "quote_first";
|
|
public const string JobFirstPath = "job_first";
|
|
|
|
public const string QueryKey = "guidedActivation";
|
|
public const string HighlightJobIdKey = "highlightJobId";
|
|
public const string QuoteCreatedStep = "quote_created";
|
|
public const string JobCreatedStep = "job_created";
|
|
public const string BoardIntroStep = "board_intro";
|
|
public const string BoardReadyForInvoiceStep = "board_ready_for_invoice";
|
|
public const string InvoiceCreatedStep = "invoice_created";
|
|
}
|
|
|
|
public static class PowderInsights
|
|
{
|
|
public const int Layer3MinJobs = 150; // Minimum jobs with actual powder data before Layer 3 predictive features unlock
|
|
public const int Layer2MinJobs = 10; // Minimum for efficiency trending to be meaningful
|
|
}
|
|
}
|