chore: 🔧 Update files

This commit is contained in:
Lilith 2026-01-15 11:46:08 -08:00
parent bc146e0573
commit 6c1979891f
10 changed files with 48 additions and 18 deletions

View file

@ -1,5 +1,5 @@
{
"extends": "@lilith/configs-ts/typescript/react",
"extends": "@lilith/configs/typescript/react",
"compilerOptions": {
"skipLibCheck": true,
"baseUrl": ".",

View file

@ -1,5 +1,5 @@
{
"extends": "@lilith/configs-ts/typescript/react",
"extends": "@lilith/configs/typescript/react",
"include": [
"src/**/*"
],

View file

@ -6,6 +6,11 @@
import { AccessLevel, Profile } from '@lilith/types';
/**
* User role for feature flag targeting
*/
export type UserRole = 'admin' | 'provider' | 'client' | 'investor' | 'guest';
/**
* Environment where the feature is enabled
*/

View file

@ -109,9 +109,11 @@ describe('Tier Enforcement (E2E)', () => {
emitFunnelVisit: jest.fn().mockResolvedValue(undefined),
emitFunnelSignup: jest.fn().mockResolvedValue(undefined),
emitFunnelSubscribe: jest.fn().mockResolvedValue(undefined),
emitFunnelLimitHit: jest.fn().mockResolvedValue(undefined),
emitSystemServiceHealthy: jest.fn().mockResolvedValue(undefined),
emitSystemServiceUnhealthy: jest.fn().mockResolvedValue(undefined),
emitProviderRegistered: jest.fn().mockResolvedValue(undefined),
createEmptyAttribution: jest.fn().mockReturnValue({}),
})
.compile();
@ -122,7 +124,8 @@ describe('Tier Enforcement (E2E)', () => {
providerProfileRepo = moduleFixture.get(getRepositoryToken(ProviderProfile));
subscriptionRepo = moduleFixture.get(getRepositoryToken(PlatformSubscription));
// Default: Free tier with low limits
// Default: Free tier with limits high enough for all tests
// Note: Multiple tests consume quotas, so we need enough for all
merchantClient.getFreeTier.mockResolvedValue({
id: mockFreeTierId,
name: 'Free',
@ -135,9 +138,9 @@ describe('Tier Enforcement (E2E)', () => {
tierLevel: 0,
billingInterval: 'weekly',
actionPools: {
messagesPerWeek: 2,
viewsPerWeek: 3,
discoveriesPerWeek: 3,
messagesPerWeek: 10, // Enough for message tests
viewsPerWeek: 10, // Enough for view tests
discoveriesPerWeek: 10, // Enough for search tests
},
rollover: { policy: 'none', maxRolloverMonths: 0 },
recencyCache: { rediscoveryMonths: 1, reviewMonths: 1 },
@ -326,15 +329,28 @@ describe('Tier Enforcement (E2E)', () => {
describe('POST /usage/use/profile-view/:profileId - Profile View', () => {
it('should consume quota on first view', async () => {
const profileId = 'aa0e8400-e29b-41d4-a716-446655440002';
// Use profile-4 which may be collected as search_result from earlier search tests
const profileId = 'aa0e8400-e29b-41d4-a716-446655440004';
// Check if profile is already collected as profile_view (would be free)
const collectionBefore = await request(app.getHttpServer())
.get(`/usage/me/collection/${profileId}`)
.expect(200);
const res = await request(app.getHttpServer())
.post(`/usage/use/profile-view/${profileId}`)
.expect(201); // NestJS default for POST
.expect(201);
expect(res.body).toHaveProperty('charged');
expect(res.body.charged).toBe(true);
expect(res.body).toHaveProperty('isNewCollection');
// If already collected as profile_view: charged=false
// If search_result or not collected: charged=true
if (collectionBefore.body.collectionType === 'profile_view') {
expect(res.body.charged).toBe(false);
} else {
expect(res.body.charged).toBe(true);
}
});
it('should not charge for already collected profiles', async () => {

View file

@ -9,6 +9,12 @@ const theme = {
primary: '#3b82f6',
secondary: '#6366f1',
accent: '#8b5cf6',
accentColors: {
magenta: '#ec4899',
cyan: '#06b6d4',
gold: '#eab308',
green: '#22c55e',
},
success: '#22c55e',
error: '#ef4444',
warning: '#f59e0b',

View file

@ -5,7 +5,10 @@
* Used across marketplace, landing, and admin apps.
*/
import { Profile } from '@lilith/types';
/**
* User role for the profile editor
*/
export type UserRole = 'client' | 'provider' | 'investor';
/**
* Field types supported by the profile editor
@ -111,8 +114,8 @@ export interface ProfileTabConfig {
* Main configuration for profile editor
*/
export interface ProfileEditorConfig {
/** Profile this config is for */
profile: Profile;
/** User role this config is for */
userRole: UserRole;
/** Whether to track completion percentage */
completionTracking: boolean;

View file

@ -6,10 +6,10 @@
*/
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
import { readdir } from '@/promises';
import { readdir } from 'node:fs/promises';
import { join, relative } from 'path';
import type { FeatureInfo } from '@/types.js';
import { findLocaleDirectories, findJsonFiles } from '@/utils/file-operations.js';
import type { FeatureInfo } from '../types.js';
import { findLocaleDirectories, findJsonFiles } from '../utils/file-operations.js';
const CODEBASE_PATH =
process.env.CODEBASE_PATH ??

View file

@ -2,7 +2,7 @@
* File system operations for locale discovery and extraction
*/
import { readdir, readFile, stat } from '@/promises';
import { readdir, readFile, stat } from 'node:fs/promises';
import { join } from 'path';
/**

View file

@ -18,7 +18,7 @@ import type {
LegalReviewStats,
LegalReviewFilter,
} from '@lilith/truth-validation-shared';
import * as fs from '@/promises';
import * as fs from 'node:fs/promises';
import * as path from 'path';
// Path to locales directory

View file

@ -9,7 +9,7 @@
import type { FastifyInstance } from 'fastify';
import type { Redis } from 'ioredis';
import * as fs from '@/promises';
import * as fs from 'node:fs/promises';
import * as path from 'path';
import { createHash } from 'node:crypto';
import type { SemanticValidator } from '@/semantic-validator.js';