@devdash/bofrid-api-types 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +24 -0
  2. package/dist/app.d.ts +23 -0
  3. package/dist/dev.d.ts +6 -0
  4. package/dist/export-openapi.d.ts +9 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/lib/auth.d.ts +20 -0
  7. package/dist/lib/criipto-bankid.d.ts +45 -0
  8. package/dist/lib/datalake.d.ts +7 -0
  9. package/dist/lib/docs-filter.d.ts +15 -0
  10. package/dist/lib/email-action-token.d.ts +26 -0
  11. package/dist/lib/email-utm.d.ts +42 -0
  12. package/dist/lib/email.d.ts +94 -0
  13. package/dist/lib/env.d.ts +18 -0
  14. package/dist/lib/errors.d.ts +6 -0
  15. package/dist/lib/helpers.d.ts +6 -0
  16. package/dist/lib/logger.d.ts +25 -0
  17. package/dist/lib/markets.d.ts +1 -0
  18. package/dist/lib/org-number.d.ts +5 -0
  19. package/dist/lib/ownership.d.ts +47 -0
  20. package/dist/lib/pdf-watermark.d.ts +25 -0
  21. package/dist/lib/personnummer.d.ts +14 -0
  22. package/dist/lib/posthog.d.ts +51 -0
  23. package/dist/lib/premium.d.ts +13 -0
  24. package/dist/lib/profile-resolver.d.ts +14 -0
  25. package/dist/lib/redirect-state.d.ts +40 -0
  26. package/dist/lib/revalidate.d.ts +23 -0
  27. package/dist/lib/schemas.d.ts +21 -0
  28. package/dist/lib/sentry.d.ts +31 -0
  29. package/dist/lib/slug.d.ts +5 -0
  30. package/dist/lib/sms.d.ts +22 -0
  31. package/dist/lib/system-log.d.ts +31 -0
  32. package/dist/lib/webhook-events.d.ts +26 -0
  33. package/dist/lib/webhooks.d.ts +28 -0
  34. package/dist/middleware/auth-debug.d.ts +17 -0
  35. package/dist/middleware/auth.d.ts +19 -0
  36. package/dist/middleware/bibi-logger.d.ts +6 -0
  37. package/dist/middleware/cors.d.ts +1 -0
  38. package/dist/middleware/request-id.d.ts +10 -0
  39. package/dist/middleware/sentry-context.d.ts +8 -0
  40. package/dist/routes/activity-feed.d.ts +64 -0
  41. package/dist/routes/admin-bevakningar.d.ts +200 -0
  42. package/dist/routes/admin-companies.d.ts +381 -0
  43. package/dist/routes/admin-email-jobs.d.ts +257 -0
  44. package/dist/routes/admin-email-logs.d.ts +9 -0
  45. package/dist/routes/admin-fb-leads.d.ts +32 -0
  46. package/dist/routes/admin-import.d.ts +188 -0
  47. package/dist/routes/admin-login-history.d.ts +9 -0
  48. package/dist/routes/admin-marketing.d.ts +15 -0
  49. package/dist/routes/admin-metabase.d.ts +9 -0
  50. package/dist/routes/admin-notifications.d.ts +7 -0
  51. package/dist/routes/admin-paying-customers.d.ts +74 -0
  52. package/dist/routes/admin-sessions.d.ts +10 -0
  53. package/dist/routes/admin-stats.d.ts +380 -0
  54. package/dist/routes/admin-system-logs.d.ts +10 -0
  55. package/dist/routes/admin-users.d.ts +299 -0
  56. package/dist/routes/admin-webhooks.d.ts +276 -0
  57. package/dist/routes/api-keys.d.ts +123 -0
  58. package/dist/routes/applications.d.ts +385 -0
  59. package/dist/routes/auth.d.ts +15 -0
  60. package/dist/routes/billing.d.ts +369 -0
  61. package/dist/routes/bostadsmerit.d.ts +51 -0
  62. package/dist/routes/companies.d.ts +842 -0
  63. package/dist/routes/contact-reveals.d.ts +102 -0
  64. package/dist/routes/conversations/handlers/conversation.d.ts +5 -0
  65. package/dist/routes/conversations/handlers/initiate.d.ts +4 -0
  66. package/dist/routes/conversations/handlers/messages.d.ts +5 -0
  67. package/dist/routes/conversations/handlers/state.d.ts +5 -0
  68. package/dist/routes/conversations/helpers/access.d.ts +11 -0
  69. package/dist/routes/conversations/helpers/enrich-conversation.d.ts +58 -0
  70. package/dist/routes/conversations/helpers/identity.d.ts +43 -0
  71. package/dist/routes/conversations/helpers/notify-recipient.d.ts +10 -0
  72. package/dist/routes/conversations/helpers/reconcile-reveal.d.ts +10 -0
  73. package/dist/routes/conversations/helpers/scrub-contact.d.ts +1 -0
  74. package/dist/routes/conversations/index.d.ts +422 -0
  75. package/dist/routes/conversations/routes.d.ts +924 -0
  76. package/dist/routes/conversations/schemas.d.ts +216 -0
  77. package/dist/routes/cron.d.ts +27 -0
  78. package/dist/routes/documents.d.ts +493 -0
  79. package/dist/routes/email-actions.d.ts +8 -0
  80. package/dist/routes/fastighetslista.d.ts +94 -0
  81. package/dist/routes/geo.d.ts +518 -0
  82. package/dist/routes/geocoding.d.ts +192 -0
  83. package/dist/routes/health.d.ts +43 -0
  84. package/dist/routes/housing-history.d.ts +381 -0
  85. package/dist/routes/index.d.ts +15321 -0
  86. package/dist/routes/leads.d.ts +281 -0
  87. package/dist/routes/listing-helpers.d.ts +33 -0
  88. package/dist/routes/listing-publications.d.ts +636 -0
  89. package/dist/routes/listings.d.ts +1846 -0
  90. package/dist/routes/location-interests.d.ts +754 -0
  91. package/dist/routes/lookup.d.ts +109 -0
  92. package/dist/routes/mejl.d.ts +377 -0
  93. package/dist/routes/profiles.d.ts +281 -0
  94. package/dist/routes/properties.d.ts +1266 -0
  95. package/dist/routes/public-listings.d.ts +1137 -0
  96. package/dist/routes/public-profiles.d.ts +293 -0
  97. package/dist/routes/references.d.ts +695 -0
  98. package/dist/routes/search-partners.d.ts +4 -0
  99. package/dist/routes/site-config.d.ts +103 -0
  100. package/dist/routes/storage.d.ts +367 -0
  101. package/dist/routes/tenant-boost.d.ts +229 -0
  102. package/dist/routes/tenants.d.ts +336 -0
  103. package/dist/routes/track.d.ts +19 -0
  104. package/dist/routes/translate.d.ts +51 -0
  105. package/dist/routes/users.d.ts +517 -0
  106. package/dist/routes/verification.d.ts +175 -0
  107. package/dist/routes/webhooks.d.ts +9 -0
  108. package/dist/rpc.d.ts +11 -0
  109. package/dist/serve.d.ts +5 -0
  110. package/dist/services/activity-feed/activity-feed.service.d.ts +26 -0
  111. package/dist/services/applications/approval.service.d.ts +17 -0
  112. package/dist/services/auth/bankid-login.service.d.ts +40 -0
  113. package/dist/services/billing/constants.d.ts +2 -0
  114. package/dist/services/billing/contact-billing.service.d.ts +59 -0
  115. package/dist/services/billing/customer.service.d.ts +14 -0
  116. package/dist/services/billing/invoice-item.service.d.ts +49 -0
  117. package/dist/services/billing/invoice.service.d.ts +21 -0
  118. package/dist/services/billing/listing-upgrade-checkout.service.d.ts +45 -0
  119. package/dist/services/billing/purchase-receipt-email.d.ts +23 -0
  120. package/dist/services/billing/reveal-allowance.service.d.ts +33 -0
  121. package/dist/services/billing/stripe.d.ts +6 -0
  122. package/dist/services/billing/subscription.service.d.ts +21 -0
  123. package/dist/services/billing/types.d.ts +64 -0
  124. package/dist/services/billing/verify-session.service.d.ts +17 -0
  125. package/dist/services/billing/webhook.service.d.ts +8 -0
  126. package/dist/services/bostadsmerit/calculator.d.ts +51 -0
  127. package/dist/services/bostadsmerit/couple-calculator.d.ts +46 -0
  128. package/dist/services/bostadsmerit/tracker.service.d.ts +45 -0
  129. package/dist/services/chat-access/unlock-chat.service.d.ts +62 -0
  130. package/dist/services/conversations/upsert-conversation.d.ts +11 -0
  131. package/dist/services/email-jobs/email-job-sender.d.ts +7 -0
  132. package/dist/services/email-jobs/email-job.service.d.ts +67 -0
  133. package/dist/services/geo/bevakning-matching.service.d.ts +67 -0
  134. package/dist/services/geo/geo-listings.service.d.ts +38 -0
  135. package/dist/services/geo/geo.service.d.ts +233 -0
  136. package/dist/services/geo/geocode.service.d.ts +16 -0
  137. package/dist/services/geo/market-insights-by-coords.service.d.ts +67 -0
  138. package/dist/services/geo/market-insights.service.d.ts +44 -0
  139. package/dist/services/geo/market-overview.service.d.ts +42 -0
  140. package/dist/services/homii/image.d.ts +24 -0
  141. package/dist/services/homii/index.d.ts +12 -0
  142. package/dist/services/homii/location.d.ts +32 -0
  143. package/dist/services/homii/mapper.d.ts +41 -0
  144. package/dist/services/homii/types.d.ts +91 -0
  145. package/dist/services/leads/constants.d.ts +32 -0
  146. package/dist/services/leads/generate-leads.service.d.ts +38 -0
  147. package/dist/services/leads/matching.service.d.ts +55 -0
  148. package/dist/services/leads/tier.service.d.ts +6 -0
  149. package/dist/services/leads/types.d.ts +27 -0
  150. package/dist/services/listings/seo.service.d.ts +57 -0
  151. package/dist/services/listings/status.d.ts +37 -0
  152. package/dist/services/mejl/client.d.ts +38 -0
  153. package/dist/services/mrkoll/client.d.ts +95 -0
  154. package/dist/services/mrkoll/import.d.ts +38 -0
  155. package/dist/services/mrkoll/match.d.ts +35 -0
  156. package/dist/services/notifications/bibi-projects.d.ts +43 -0
  157. package/dist/services/notifications/bibi.d.ts +229 -0
  158. package/dist/services/profiles/bankid-verify.d.ts +23 -0
  159. package/dist/services/realtime.d.ts +14 -0
  160. package/dist/services/references/history-linker.d.ts +19 -0
  161. package/dist/services/tenant-boost/constants.d.ts +120 -0
  162. package/dist/services/tenant-boost/tenant-boost.service.d.ts +59 -0
  163. package/package.json +29 -0
package/dist/rpc.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * RPC type export for Hono client consumers (apps/web).
3
+ *
4
+ * This file exists to provide a clean import path that doesn't
5
+ * pull in implementation files with @/ path aliases. The type is
6
+ * re-exported from the route chain in routes/index.ts.
7
+ *
8
+ * Usage in apps/web:
9
+ * import type { AppType } from "@bofrid/api/rpc";
10
+ */
11
+ export type { AppType } from "./routes/index";
@@ -0,0 +1,5 @@
1
+ declare const _default: {
2
+ port: number;
3
+ fetch: (request: Request, Env?: unknown, executionCtx?: import("hono").ExecutionContext) => Response | Promise<Response>;
4
+ };
5
+ export default _default;
@@ -0,0 +1,26 @@
1
+ type Severity = "action_required" | "waiting" | "info" | "completed";
2
+ type Category = "application" | "document" | "reference" | "identity" | "listing_review" | "listing_rejected" | "listing_upgraded" | "incoming_application" | "invoice" | "company_invite";
3
+ export interface ActivityItem {
4
+ id: string;
5
+ category: Category;
6
+ severity: Severity;
7
+ title: string;
8
+ description?: string;
9
+ subtitle?: string;
10
+ imageUrl?: string;
11
+ avatarUrl?: string;
12
+ avatarFallback?: string;
13
+ href: string;
14
+ resourceId?: string;
15
+ createdAt: string;
16
+ completedAt?: string;
17
+ }
18
+ interface ActivityFeedResult {
19
+ items: ActivityItem[];
20
+ historyItems: ActivityItem[];
21
+ counts: Record<Category, number>;
22
+ total: number;
23
+ }
24
+ type Locale = "sv" | "en";
25
+ export declare function getActivityFeed(profileId: string, locale: Locale, view?: "tenant" | "landlord" | "company"): Promise<ActivityFeedResult>;
26
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Check if a tenant has the required documents for auto-approval.
3
+ * Returns the list of missing categories.
4
+ */
5
+ export declare function checkRequiredDocs(tenantId: string): Promise<{
6
+ hasAll: boolean;
7
+ missing: string[];
8
+ }>;
9
+ /**
10
+ * Execute the full approval flow for an application:
11
+ * 1. Set adminApproved = true
12
+ * 2. Create/upgrade lead
13
+ * 3. Send landlord notification
14
+ */
15
+ export declare function executeApprovalFlow(applicationId: string, approverProfileId: string | null): Promise<{
16
+ leadCreated: boolean;
17
+ }>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * BankID Login Service — handles user lookup/creation and session creation
3
+ * for the BankID login flow (unauthenticated users).
4
+ */
5
+ interface FoundUser {
6
+ profileId: string;
7
+ authUserId: string;
8
+ email: string | null;
9
+ }
10
+ /**
11
+ * Find an existing active user by personnummer.
12
+ */
13
+ export declare function findUserByPersonnummer(personnummer: string): Promise<FoundUser | null>;
14
+ interface BankIDUserData {
15
+ personnummer: string;
16
+ displayName: string;
17
+ givenName: string;
18
+ surname: string;
19
+ }
20
+ interface CreatedUser {
21
+ authUserId: string;
22
+ profileId: string;
23
+ email: string;
24
+ }
25
+ /**
26
+ * Create a new user from BankID data with a deterministic placeholder email.
27
+ * If a BA user with the placeholder email already exists (incomplete previous flow),
28
+ * reuse it.
29
+ */
30
+ export declare function createNewBankIDUser(bankIDData: BankIDUserData): Promise<CreatedUser>;
31
+ /**
32
+ * Create a Better Auth session for a user by email.
33
+ * Returns a Response with Set-Cookie headers.
34
+ *
35
+ * Uses an email-keyed OTP resolver map so concurrent BankID logins on the
36
+ * same warm serverless instance don't clobber each other's OTP.
37
+ */
38
+ export declare function createSessionForUser(email: string, requestHeaders: Headers): Promise<Response>;
39
+ export declare function recordBankIDLogin(profileId: string, email: string | null, ipAddress: string | null, userAgent: string | null): Promise<void>;
40
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Default VAT rate for Swedish domestic invoices (25%) */
2
+ export declare const DEFAULT_VAT_RATE = 25;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Contact Billing Service — read-only billing view + Stripe customer queries.
3
+ *
4
+ * The pay-per-reveal charge path was removed when single-reveal checkout was
5
+ * retired. Listings now pay per-listing (listing upgrade) and tenants pay
6
+ * per-subscription (Boost); both use Stripe Checkout directly rather than
7
+ * the invoice-items pipeline. The functions here read historical invoice
8
+ * items + Stripe customer state for the billing dashboard.
9
+ */
10
+ import type { ContactBillingUsage, StripeInvoiceSummary } from "./types";
11
+ /**
12
+ * Get monthly usage stats for billing dashboard.
13
+ * Now reads from local invoice items for accurate breakdown.
14
+ */
15
+ export declare function getMonthlyUsage(userId: string): Promise<ContactBillingUsage>;
16
+ /**
17
+ * Check if the user's Stripe customer has a default payment method.
18
+ */
19
+ export declare function checkPaymentMethod(userId: string): Promise<{
20
+ hasPaymentMethod: boolean;
21
+ brand?: string;
22
+ last4?: string;
23
+ }>;
24
+ /**
25
+ * List invoices — reads from local DB first, falls back to Stripe for historical.
26
+ */
27
+ export declare function getInvoices(userId: string): Promise<StripeInvoiceSummary[]>;
28
+ /**
29
+ * Create a Stripe Customer Portal session so the user can manage
30
+ * payment methods, view invoices, and download receipts.
31
+ */
32
+ export declare function createPortalSession(userId: string, returnUrl: string): Promise<string>;
33
+ /**
34
+ * Get the billing email from Stripe customer record.
35
+ * Stripe is the source of truth for invoice/billing email.
36
+ */
37
+ export declare function getBillingEmail(userId: string): Promise<{
38
+ email: string | null;
39
+ }>;
40
+ /**
41
+ * Update the billing email on the Stripe customer record.
42
+ * Stripe is the source of truth — no local DB write needed.
43
+ */
44
+ export declare function updateBillingEmail(userId: string, email: string): Promise<{
45
+ email: string;
46
+ }>;
47
+ /**
48
+ * Get Stripe receipts (from charges) for the authenticated user.
49
+ * Each successful Stripe Checkout creates a Charge with a receipt_url.
50
+ */
51
+ export declare function getReceipts(userId: string): Promise<{
52
+ id: string;
53
+ amount: number;
54
+ currency: string;
55
+ description: string | null;
56
+ receiptUrl: string | null;
57
+ created: number;
58
+ paymentIntentId: string | null;
59
+ }[]>;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Customer Service — Stripe customer management for Bofrid users.
3
+ */
4
+ import type { Subscriber } from "./types";
5
+ /**
6
+ * Resolve subscriber data for Stripe customer creation.
7
+ * Determines company vs user from businessType field.
8
+ */
9
+ export declare function resolveSubscriber(userId: string): Promise<Subscriber | null>;
10
+ /**
11
+ * Get or create Stripe customer for a user.
12
+ * Validates existing customer, adds VAT tax_id for companies.
13
+ */
14
+ export declare function getOrCreateStripeCustomer(userId: string, email: string, name: string, organizationNumber?: string): Promise<string>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Invoice Item Service — read-only queries against historical invoice items.
3
+ *
4
+ * Creation of new items was retired with the single-reveal checkout flow.
5
+ * Listing upgrades and Boost subscriptions go straight to Stripe Checkout;
6
+ * the rows here are kept for the billing dashboard and historical reports.
7
+ */
8
+ import type { LocalInvoiceItem } from "./types";
9
+ /**
10
+ * Returns the current billing period as "YYYY-MM".
11
+ */
12
+ export declare function getCurrentBillingPeriod(): string;
13
+ /**
14
+ * Query pending invoice items for a customer, optionally filtered by billing period.
15
+ */
16
+ export declare function getPendingItems(customerId: string, billingPeriod?: string): Promise<LocalInvoiceItem[]>;
17
+ /**
18
+ * Get all invoice items for a customer in a billing period (any status).
19
+ */
20
+ export declare function getItemsForPeriod(customerId: string, billingPeriod?: string): Promise<LocalInvoiceItem[]>;
21
+ /**
22
+ * Void an invoice item. Sets status to "void" and attempts to delete
23
+ * the Stripe invoice item if it hasn't been invoiced yet.
24
+ */
25
+ export declare function voidInvoiceItem(itemId: string): Promise<void>;
26
+ /**
27
+ * Get usage breakdown by invoice item type for a customer in the current period.
28
+ */
29
+ export declare function getUsageBreakdown(customerId: string): Promise<{
30
+ type: string;
31
+ count: number;
32
+ totalOre: number;
33
+ }[]>;
34
+ /**
35
+ * Get transaction history with property address info.
36
+ * Joins invoice items → listings → properties to enrich each item
37
+ * with the street/city of the listing that was revealed.
38
+ */
39
+ export declare function getTransactionHistory(customerId: string, limit?: number): Promise<{
40
+ id: string;
41
+ type: string;
42
+ description: string;
43
+ totalOre: number;
44
+ status: string;
45
+ billingPeriod: string;
46
+ createdAt: Date;
47
+ propertyAddress: string | null;
48
+ paymentIntentId: string | null;
49
+ }[]>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Invoice Service — Local invoice records synced from Stripe webhooks.
3
+ */
4
+ import type Stripe from "stripe";
5
+ import type { LocalInvoiceSummary, LocalInvoiceItem } from "./types";
6
+ /**
7
+ * Upsert a local invoice from Stripe webhook data.
8
+ * Called on invoice.finalized, invoice.paid, invoice.voided, etc.
9
+ */
10
+ export declare function syncStripeInvoice(stripeInvoice: Stripe.Invoice, customerId: string, companyId?: string): Promise<string>;
11
+ /**
12
+ * Query local invoices for a customer, ordered by most recent.
13
+ */
14
+ export declare function getCustomerInvoices(customerId: string, limit?: number): Promise<LocalInvoiceSummary[]>;
15
+ /**
16
+ * Get an invoice with its line items for detail view.
17
+ */
18
+ export declare function getInvoiceWithItems(invoiceId: string, customerId: string): Promise<{
19
+ invoice: LocalInvoiceSummary;
20
+ items: LocalInvoiceItem[];
21
+ } | null>;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Listing Upgrade Checkout Service
3
+ *
4
+ * Creates Stripe Checkout sessions for upgrading a listing (500 SEK).
5
+ * On webhook completion, sets `listings.upgradedAt` so all reveals are free.
6
+ */
7
+ import { type UpgradeFeature } from "../../services/leads/constants";
8
+ /** First-listing discount: 50% off */
9
+ export declare const FIRST_LISTING_DISCOUNT_PERCENT = 50;
10
+ /**
11
+ * Check if a landlord (or their company) has ever upgraded a listing before.
12
+ * Used to determine first-listing discount eligibility.
13
+ *
14
+ * Checks both personal properties (landlordId) and company properties (companyId)
15
+ * so the discount is per-customer, not per-user.
16
+ */
17
+ export declare function hasAnyUpgradedListing(userId: string): Promise<boolean>;
18
+ /**
19
+ * Create a Stripe Checkout session for upgrading a listing.
20
+ */
21
+ export declare function createListingUpgradeCheckout(userId: string, listingId: string, returnUrl: string): Promise<{
22
+ alreadyUpgraded: true;
23
+ } | {
24
+ checkoutUrl: string;
25
+ }>;
26
+ /**
27
+ * Complete a listing upgrade after Stripe Checkout success (webhook handler).
28
+ */
29
+ export declare function completeListingUpgradeCheckout(session: {
30
+ id: string;
31
+ metadata: Record<string, string> | null;
32
+ }): Promise<void>;
33
+ /**
34
+ * Check if a listing is upgraded (all reveals free).
35
+ */
36
+ export declare function isListingUpgraded(listingId: string): Promise<boolean>;
37
+ /**
38
+ * Get the upgrade tier for a listing (null if not upgraded).
39
+ */
40
+ export declare function getListingUpgradeTier(listingId: string): Promise<number | null>;
41
+ /**
42
+ * Check if a listing has a specific upgrade feature.
43
+ * Returns false if not upgraded or if the tier doesn't include the feature.
44
+ */
45
+ export declare function listingHasUpgradeFeature(listingId: string, feature: UpgradeFeature): Promise<boolean>;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Purchase Receipt Email — sends a receipt after a successful Stripe Checkout.
3
+ *
4
+ * For company users, sends to the company email (or Stripe billing email)
5
+ * and uses the company name as recipient.
6
+ */
7
+ interface SendReceiptParams {
8
+ userId: string;
9
+ productName: string;
10
+ amountOre: number;
11
+ /** VAT rate as integer percent. Defaults to DEFAULT_VAT_RATE (25%). */
12
+ vatRate?: number;
13
+ }
14
+ /**
15
+ * Resolve subscriber info and send a purchase receipt email.
16
+ *
17
+ * Email priority:
18
+ * 1. Stripe billing email (if set — source of truth for invoices/receipts)
19
+ * 2. Company email (for company users)
20
+ * 3. User profile email (fallback)
21
+ */
22
+ export declare function sendPurchaseReceipt(params: SendReceiptParams): Promise<void>;
23
+ export {};
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Reveal Allowance Service — Free monthly candidate reveals per landlord.
3
+ *
4
+ * Each landlord gets FREE_REVEALS_PER_MONTH reveals per calendar month.
5
+ * Admins can override this per-user via `profiles.freeRevealsPerMonth`
6
+ * or per-company via `companies.freeRevealsPerMonth`.
7
+ *
8
+ * Only reveals with `reveal_reason = 'quota'` consume the allowance. Reveals
9
+ * triggered by listing-premium, tenant-boost, or admin actions are recorded
10
+ * with their own reason and never count against the landlord's monthly budget.
11
+ */
12
+ /** Default number of free reveals per landlord per calendar month */
13
+ export declare const FREE_REVEALS_PER_MONTH = 2;
14
+ /**
15
+ * Count how many quota-consuming reveals this landlord has used this month.
16
+ *
17
+ * A revealed (listing_id, tenant_id) pair counts at most once, even when the
18
+ * unlock is mirrored across both applications and leads. Only reason='quota'
19
+ * is counted — listing-premium / tenant-boost / admin unlocks are recorded
20
+ * but never charged against the monthly budget.
21
+ */
22
+ export declare function countRevealsThisMonth(profileId: string): Promise<number>;
23
+ /** Reveal allowance status for a landlord. */
24
+ export declare function getRevealAllowance(profileId: string): Promise<{
25
+ used: number;
26
+ limit: number;
27
+ remaining: number;
28
+ resetDate: string;
29
+ }>;
30
+ /** Whether the landlord can spend a free reveal right now. */
31
+ export declare function canReveal(profileId: string): Promise<boolean>;
32
+ /** Set the per-user reveal limit override. Pass `null` to revert to global default. */
33
+ export declare function setUserRevealLimit(profileId: string, limit: number | null): Promise<void>;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Stripe Client — Lazy initialization for API layer.
3
+ */
4
+ import Stripe from "stripe";
5
+ export declare function getStripe(): Stripe;
6
+ export declare function getWebhookSecret(): string;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Subscription Service — Fetch Stripe subscriptions for a user.
3
+ */
4
+ export interface SubscriptionSummary {
5
+ id: string;
6
+ status: string;
7
+ productName: string;
8
+ priceAmountOre: number;
9
+ currency: string;
10
+ interval: string;
11
+ created: number;
12
+ currentPeriodEnd: number | null;
13
+ canceledAt: number | null;
14
+ cancelAt: number | null;
15
+ endedAt: number | null;
16
+ }
17
+ /**
18
+ * List all subscriptions for a user, including canceled.
19
+ * Returns empty array if user has no Stripe customer.
20
+ */
21
+ export declare function getSubscriptions(userId: string): Promise<SubscriptionSummary[]>;
@@ -0,0 +1,64 @@
1
+ export type SubscriberType = "user" | "company";
2
+ export interface Subscriber {
3
+ id: string;
4
+ type: SubscriberType;
5
+ email: string;
6
+ name: string;
7
+ companyId?: string;
8
+ organizationNumber?: string;
9
+ }
10
+ export type InvoiceItemStatus = "pending" | "invoiced" | "void";
11
+ export type InvoiceStatus = "draft" | "open" | "paid" | "void" | "uncollectible";
12
+ export interface LocalInvoiceItem {
13
+ id: string;
14
+ type: string;
15
+ description: string;
16
+ quantity: number;
17
+ unitPriceOre: number;
18
+ totalOre: number;
19
+ status: string;
20
+ billingPeriod: string;
21
+ stripeInvoiceItemId: string | null;
22
+ sourceType: string | null;
23
+ sourceId: string | null;
24
+ createdAt: Date;
25
+ }
26
+ export interface LocalInvoiceSummary {
27
+ id: string;
28
+ stripeInvoiceId: string;
29
+ invoiceNumber: string | null;
30
+ billingPeriod: string;
31
+ status: string;
32
+ subtotalOre: number;
33
+ vatOre: number;
34
+ totalOre: number;
35
+ currency: string;
36
+ hostedInvoiceUrl: string | null;
37
+ invoicePdf: string | null;
38
+ itemCount: number;
39
+ paidAt: Date | null;
40
+ createdAt: Date;
41
+ }
42
+ export interface BillingUsageBreakdown {
43
+ type: string;
44
+ count: number;
45
+ totalOre: number;
46
+ }
47
+ export interface ContactBillingUsage {
48
+ revealsThisMonth: number;
49
+ totalAmountThisMonth: number;
50
+ hasPaymentMethod: boolean;
51
+ breakdown: BillingUsageBreakdown[];
52
+ pendingItemCount: number;
53
+ pendingTotalOre: number;
54
+ }
55
+ export interface StripeInvoiceSummary {
56
+ id: string;
57
+ number: string | null;
58
+ status: string | null;
59
+ amountDue: number;
60
+ currency: string;
61
+ created: number;
62
+ hostedInvoiceUrl: string | null;
63
+ invoicePdf: string | null;
64
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * verify-session — resolve a Stripe Checkout Session by ID and apply state.
3
+ *
4
+ * Industry-standard fulfillment pattern: client returns from Stripe with the
5
+ * checkout session ID in the URL, posts it here, we look it up authoritatively
6
+ * on Stripe and apply any state that the async webhook hasn't yet. Idempotent
7
+ * with the webhook handler — if the webhook already ran, this is a no-op read.
8
+ */
9
+ export type CheckoutKind = "boost" | "listing_upgrade" | "unknown";
10
+ export interface VerifySessionResult {
11
+ /** "complete" when checkout finished + state applied; "pending" when payment is still processing; "expired" otherwise */
12
+ status: "complete" | "pending" | "expired";
13
+ kind: CheckoutKind;
14
+ /** True only if this verification is allowed to be acted on by the caller (matches the requesting user) */
15
+ ownedByUser: boolean;
16
+ }
17
+ export declare function verifyCheckoutSession(sessionId: string, userId: string): Promise<VerifySessionResult>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Webhook Service — Handles Stripe webhook events for invoice lifecycle.
3
+ */
4
+ import type Stripe from "stripe";
5
+ /**
6
+ * Dispatch a Stripe webhook event to the appropriate handler.
7
+ */
8
+ export declare function handleStripeWebhookEvent(event: Stripe.Event): Promise<void>;
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Bostadsmerit Core Calculation — Pure Functions (No DB)
3
+ *
4
+ * SCORING SYSTEM (3 categories, 80p max):
5
+ *
6
+ * 1. DOKUMENT (30p max)
7
+ * - credit_report: 5p uploaded + 5p verified = 10p
8
+ * - criminal_record_extract: 5p uploaded + 5p verified = 10p
9
+ * - income_doc: 5p uploaded + 5p verified = 10p
10
+ *
11
+ * 2. BOENDEHISTORIK (30p max capped)
12
+ * - Import from Folkbokföringen: 5p
13
+ * - Landlord signatures: 10p each (max 3 = 30p)
14
+ *
15
+ * 3. PROFIL (20p max)
16
+ * - ID verification (BankID): 10p
17
+ * - Profile picture: 5p
18
+ * - Description: 3p
19
+ * - Title: 2p
20
+ */
21
+ export interface BostadsmeritInput {
22
+ /** Whether profile has folkbokforingRaw populated */
23
+ hasImportedFolkbokforing: boolean;
24
+ /** Whether user is ID-verified (BankID auth or approved id_doc) */
25
+ isIdVerified: boolean;
26
+ /** Whether profile has a profile picture */
27
+ hasProfilePicture: boolean;
28
+ /** Whether profile has a title set */
29
+ hasTitle: boolean;
30
+ /** Whether profile has a description set */
31
+ hasDescription: boolean;
32
+ /** Documents from bofrid_documents table */
33
+ documents: Array<{
34
+ category: string;
35
+ status: string | null;
36
+ }>;
37
+ /** Active housing references from bofrid_user_references table */
38
+ references: Array<{
39
+ type: string;
40
+ signerId: string | null;
41
+ }>;
42
+ }
43
+ export interface BostadsmeritResult {
44
+ total: number;
45
+ breakdown: {
46
+ housing: number;
47
+ documents: number;
48
+ profile: number;
49
+ };
50
+ }
51
+ export declare function calculateBostadsmerit(input: BostadsmeritInput): BostadsmeritResult;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Consolidated Couple/Group BostadsMerit Score
3
+ *
4
+ * Formula: floor(0.6 × average(scores) + 0.4 × min(scores))
5
+ *
6
+ * - Average reflects overall group quality
7
+ * - Minimum prevents one strong member from masking a weak one
8
+ * - 60/40 weighting rewards balanced couples, penalizes "carried" members
9
+ *
10
+ * Examples (couple):
11
+ * Both strong: (72, 68) → floor(0.6×70 + 0.4×68) = floor(42 + 27.2) = 69
12
+ * One weak: (75, 30) → floor(0.6×52.5 + 0.4×30) = floor(31.5 + 12) = 43
13
+ * Both weak: (35, 40) → floor(0.6×37.5 + 0.4×35) = floor(22.5 + 14) = 36
14
+ */
15
+ export interface ConsolidatedScoreResult {
16
+ /** Consolidated group score (0–80). */
17
+ consolidatedScore: number;
18
+ /** Each member's individual score. */
19
+ memberScores: Array<{
20
+ userId: string;
21
+ score: number;
22
+ breakdown: {
23
+ housing: number;
24
+ documents: number;
25
+ profile: number;
26
+ } | null;
27
+ }>;
28
+ /** ID of the member with the lowest score ("weakest link"). */
29
+ weakestMemberId: string | null;
30
+ /** Whether all members are BankID-verified. */
31
+ allBankIdVerified: boolean;
32
+ }
33
+ /**
34
+ * Calculate consolidated couple/group bostadsmerit from individual scores.
35
+ * Returns null if no scores are provided (empty group).
36
+ */
37
+ export declare function calculateConsolidatedBostadsmerit(members: Array<{
38
+ userId: string;
39
+ bostadsmeritScore: number;
40
+ bostadsmeritBreakdown: {
41
+ housing: number;
42
+ documents: number;
43
+ profile: number;
44
+ } | null;
45
+ isBankIdVerified: boolean;
46
+ }>): ConsolidatedScoreResult | null;
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Bostadsmerit Score Tracker Service
3
+ *
4
+ * Internal service (not a route) — called by other API handlers after mutations.
5
+ * Calculates score from DB data and persists the result on the profile.
6
+ */
7
+ import { type BostadsmeritResult } from "./calculator";
8
+ export type TrackingReason = "reference_signed" | "housing_imported" | "document_uploaded" | "document_verified" | "profile_updated";
9
+ export interface ScoreChangeResult {
10
+ oldScore: number;
11
+ newScore: number;
12
+ difference: number;
13
+ action: string;
14
+ breakdown?: BostadsmeritResult["breakdown"];
15
+ }
16
+ /**
17
+ * Recalculate and persist the bostadsmerit score for a user.
18
+ * Returns the full result with breakdown.
19
+ */
20
+ export declare function recalculateScore(profileId: string): Promise<BostadsmeritResult>;
21
+ /**
22
+ * Get current cached score from the profile (no recalculation).
23
+ */
24
+ export declare function getCachedScore(profileId: string): Promise<{
25
+ score: number;
26
+ breakdown: unknown;
27
+ updatedAt: Date | null;
28
+ }>;
29
+ /**
30
+ * Bulk recalculate scores for ALL profiles.
31
+ * Processes sequentially to avoid overwhelming the DB.
32
+ * NOTE: Will timeout on Vercel (60s limit) with large user counts.
33
+ * For formula changes, prefer setting bostadsmerit_updated_at = NULL
34
+ * so scores recalculate lazily on next GET /bostadsmerit/score.
35
+ */
36
+ export declare function recalculateAllScores(): Promise<{
37
+ total: number;
38
+ updated: number;
39
+ errors: number;
40
+ }>;
41
+ /**
42
+ * Track a score change after a mutation. Recalculates and returns the delta.
43
+ * Fire-and-forget safe — catches all errors internally.
44
+ */
45
+ export declare function trackBostadsmeritChange(profileId: string, action: TrackingReason): Promise<ScoreChangeResult>;