From 21657a205fe47823b91b43adfc006b0f01d9bd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9?= Date: Thu, 14 May 2026 08:28:44 +0300 Subject: [PATCH] chore(cleanup): dead code removal + DemoSeeder env-conditional + schema header drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes Audit #3 P2 batch (knip dead exports/components, DemoSeeder hygiene, schema header drift). - Remove app/resources/js/views/admin/AdminPlaceholderView.vue (unreferenced placeholder view — confirmed via repo-wide grep, only doc references remain) - npm uninstall concurrently (no script invoked it; --legacy-peer-deps for Histoire 1.0-beta.1 peerDep quirk) - 12 unused exports → internal types (remove `export` keyword): - api/admin.ts: AdminTenantsStats, ApiTenantMetrics, ApiAdminBillingSummary, ApiAdminIncidentsSummary - api/notifications.ts: NotificationEvent - api/reports.ts: ApiReportType, ApiReportFormat, ApiReportParameters, ReportCounts, ReportQuota - composables/mockBilling.ts: TxType - composables/useStatusPill.ts: StatusPillSlug All 12 are used INSIDE their own file (response shapes), just not exported externally — converting to internal types satisfies knip without losing type-checking inside the file. - DatabaseSeeder::run() — DemoSeeder runs only in local+testing envs (`migrate:fresh --seed` in dev now produces demo tenant + admin@demo.local + 3 projects + ~14 demo deals; prod environments skip) - db/schema.sql header line 4: «62 базовые таблицы» → «63 базовые таблицы (61 regular + 2 partitioned parents: deals + supplier_lead_costs)» Closes schema header drift finding from Phase 3. Verification: - vue-tsc --noEmit: 0 errors - ESLint on touched files: 0 errors - Pest --parallel: 742/739/3sk/0 failed (identical to baseline, no regressions) - 2243 assertions / 34.46s Plan: docs/superpowers/plans/2026-05-14-audit3-deferred-fixes.md Task 2. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/database/seeders/DatabaseSeeder.php | 11 +- app/package-lock.json | 138 ------------------ app/package.json | 1 - app/resources/js/api/admin.ts | 8 +- app/resources/js/api/notifications.ts | 2 +- app/resources/js/api/reports.ts | 10 +- app/resources/js/composables/mockBilling.ts | 2 +- app/resources/js/composables/useStatusPill.ts | 2 +- .../js/views/admin/AdminPlaceholderView.vue | 37 ----- db/schema.sql | 2 +- 10 files changed, 20 insertions(+), 193 deletions(-) delete mode 100644 app/resources/js/views/admin/AdminPlaceholderView.vue diff --git a/app/database/seeders/DatabaseSeeder.php b/app/database/seeders/DatabaseSeeder.php index 0fa95b70..ecc0a88b 100644 --- a/app/database/seeders/DatabaseSeeder.php +++ b/app/database/seeders/DatabaseSeeder.php @@ -12,13 +12,16 @@ class DatabaseSeeder extends Seeder /** * Seed the application's database. * - * Note: the Laravel scaffold default User::factory() seed was removed — - * наша схема использует first_name/last_name (а не "name"), и заранее - * не было сценария, где этот seed реально вызывался. PricingTierSeeder - * (Plan 4) — единственный текущий seed для dev/testing. + * PricingTierSeeder runs in all environments (prod нуждается в 7-tier + * config bootstrap'е). DemoSeeder — только local+testing: создаёт demo + * tenant + admin@demo.local + 3 проекта + ~14 demo сделок для UI smoke. */ public function run(): void { $this->call(PricingTierSeeder::class); + + if (app()->environment('local', 'testing')) { + $this->call(DemoSeeder::class); + } } } diff --git a/app/package-lock.json b/app/package-lock.json index 3d2e386e..f722e34e 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -15,7 +15,6 @@ "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.10", "axios": "^1.16.0", - "concurrently": "^9.0.1", "cross-env": "^10.1.0", "eslint": "^10.3.0", "eslint-config-prettier": "^10.1.8", @@ -4319,36 +4318,6 @@ "node": ">=18" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/change-case": { "version": "5.4.4", "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", @@ -4394,21 +4363,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4470,31 +4424,6 @@ "node": ">=14" } }, - "node_modules/concurrently": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", - "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "4.1.2", - "rxjs": "7.8.2", - "shell-quote": "1.8.3", - "supports-color": "8.1.1", - "tree-kill": "1.2.2", - "yargs": "17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -7975,16 +7904,6 @@ "dev": true, "license": "MIT" }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -9214,16 +9133,6 @@ "node": ">=20" } }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -10103,24 +10012,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", @@ -10222,35 +10113,6 @@ "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/app/package.json b/app/package.json index ab8b627d..12b0a369 100644 --- a/app/package.json +++ b/app/package.json @@ -24,7 +24,6 @@ "@vue/eslint-config-typescript": "^14.7.0", "@vue/test-utils": "^2.4.10", "axios": "^1.16.0", - "concurrently": "^9.0.1", "cross-env": "^10.1.0", "eslint": "^10.3.0", "eslint-config-prettier": "^10.1.8", diff --git a/app/resources/js/api/admin.ts b/app/resources/js/api/admin.ts index 3253a836..4f5d319c 100644 --- a/app/resources/js/api/admin.ts +++ b/app/resources/js/api/admin.ts @@ -113,7 +113,7 @@ export interface AdminTenant { created_at: string | null; } -export interface AdminTenantsStats { +interface AdminTenantsStats { total: number; active: number; trial: number; @@ -182,7 +182,7 @@ export interface ApiTenantActivityEvent { created_at: string; } -export interface ApiTenantMetrics { +interface ApiTenantMetrics { leads_today: number; leads_this_week: number; leads_this_month: number; @@ -224,7 +224,7 @@ export interface ApiAdminBillingTenant { chargeback_unrecovered_rub: string; } -export interface ApiAdminBillingSummary { +interface ApiAdminBillingSummary { total_mrr_rub: string; monthly_revenue_rub: string; overdue_count: number; @@ -262,7 +262,7 @@ export interface ApiAdminIncident { rkn_deadline_at: string | null; } -export interface ApiAdminIncidentsSummary { +interface ApiAdminIncidentsSummary { open: number; investigating: number; rkn_pending: number; diff --git a/app/resources/js/api/notifications.ts b/app/resources/js/api/notifications.ts index 120d5cf7..770c68e8 100644 --- a/app/resources/js/api/notifications.ts +++ b/app/resources/js/api/notifications.ts @@ -7,7 +7,7 @@ import { apiClient, ensureCsrfCookie } from './client'; * Mutating-вызовы (mark-read/mark-all-read/destroy) делают ensureCsrfCookie(). */ -export type NotificationEvent = +type NotificationEvent = | 'new_lead' | 'reminder' | 'low_balance' diff --git a/app/resources/js/api/reports.ts b/app/resources/js/api/reports.ts index 01b07d4c..5fe9028b 100644 --- a/app/resources/js/api/reports.ts +++ b/app/resources/js/api/reports.ts @@ -12,11 +12,11 @@ import { apiClient, ensureCsrfCookie } from './client'; export type ApiReportStatus = 'pending' | 'processing' | 'done' | 'failed'; -export type ApiReportType = 'deals_export' | 'managers_summary' | 'sources_summary' | 'billing_summary'; +type ApiReportType = 'deals_export' | 'managers_summary' | 'sources_summary' | 'billing_summary'; -export type ApiReportFormat = 'csv' | 'xlsx' | 'json' | 'pdf'; +type ApiReportFormat = 'csv' | 'xlsx' | 'json' | 'pdf'; -export interface ApiReportParameters { +interface ApiReportParameters { format: ApiReportFormat; date_from: string; date_to: string; @@ -43,14 +43,14 @@ export interface ApiReportJob { retry_max: number; } -export interface ReportCounts { +interface ReportCounts { pending: number; processing: number; done: number; failed: number; } -export interface ReportQuota { +interface ReportQuota { active: number; max_active: number; } diff --git a/app/resources/js/composables/mockBilling.ts b/app/resources/js/composables/mockBilling.ts index 37b97047..ce149de4 100644 --- a/app/resources/js/composables/mockBilling.ts +++ b/app/resources/js/composables/mockBilling.ts @@ -9,7 +9,7 @@ * - invoices (§4.5): type ∈ {invoice, upd}, format ∈ {pdf, xml_1c83}. */ -export type TxType = 'topup' | 'lead_charge' | 'refund' | 'tariff_charge'; +type TxType = 'topup' | 'lead_charge' | 'refund' | 'tariff_charge'; export type TxStatus = 'pending' | 'completed' | 'rejected'; export interface BillingTransaction { diff --git a/app/resources/js/composables/useStatusPill.ts b/app/resources/js/composables/useStatusPill.ts index 8ea56bb9..e7ef4184 100644 --- a/app/resources/js/composables/useStatusPill.ts +++ b/app/resources/js/composables/useStatusPill.ts @@ -28,7 +28,7 @@ export const STATUS_PILL_SLUGS = [ 'archived', ] as const; -export type StatusPillSlug = (typeof STATUS_PILL_SLUGS)[number]; +type StatusPillSlug = (typeof STATUS_PILL_SLUGS)[number]; const STYLES: Record = { new: { bg: 'rgba(15,110,86,0.12)', color: '#0F6E56' }, diff --git a/app/resources/js/views/admin/AdminPlaceholderView.vue b/app/resources/js/views/admin/AdminPlaceholderView.vue deleted file mode 100644 index 56c6ac08..00000000 --- a/app/resources/js/views/admin/AdminPlaceholderView.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - - - diff --git a/db/schema.sql b/db/schema.sql index 5c989a9c..f740c9a0 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,7 +1,7 @@ -- ============================================================================= -- schema.sql — единая схема БД для SaaS-аналога crm.bp-gr.ru («Лидерра») -- Версия: v8.20 (11.05.2026 — Plan 5 frontend projects UI: projects.archived_at TIMESTAMPTZ NULL для soft archive flow; tenants.limits JSONB NOT NULL DEFAULT '{}' для per-tenant project/user лимитов) --- Метрики: 62 базовые таблицы + 12 партиций / 117 индексов / 39 RLS-политик / 5 функций / 13 триггеров +-- Метрики: 63 базовые таблицы (61 regular + 2 partitioned parents: deals + supplier_lead_costs) + 12 партиций / 117 индексов / 39 RLS-политик / 5 функций / 13 триггеров -- Базовая версия: v8.19 (11.05.2026 — Plan 4 billing+csv+admin: tenants.delivered_in_month, lead_charges.charge_source + CHECK, supplier_leads.recovered_from_csv_at, supplier_csv_reconcile_log) -- Базовая версия: v8.18 (10.05.2026 — Plan 2/5 Task 1: supplier_leads SaaS-level + projects.delivered_today + 2 system_settings rows для supplier-webhook + IP allowlist defense-in-depth) -- Базовая версия: v8.17 (10.05.2026 — Plan 1/5 Task 2 fix: FK projects.supplier_b{1,2,3}_project_id → supplier_projects (ON DELETE SET NULL) + 3 partial index + CHECK chk_projects_b1_not_for_sms (defense-in-depth дублирует chk_supplier_projects_b1_not_for_sms на Project-уровне). Закрывает code-review BLOCKER#1 + WARNING#3 от 10.05.2026 поздний вечер)