metis-desk/.artifacts/account-usage/lint.log
David 0e8e15c9c2 feat: Implement account deletion functionality with UI and API integration
- Added `removeAccessAccount` function to handle account deletion in the database, ensuring no external references exist.
- Created `deleteAccount` API function to facilitate account deletion requests from the client.
- Developed `AccountDeleteDialog` component for user confirmation before account deletion, integrating with the delete API.
- Introduced resource image handling with validation for PNG uploads, including UI components for image selection and preview.
- Implemented resource icon template evolution logic to maintain icon bindings without overwriting existing fields.
- Added scripts for auditing account deletion and usage checks, ensuring robust testing of the new features.
2026-10-27 11:39:53 +01:00

442 lines
24 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

$ biome lint .
docs/auditorias/ficha-puesto-trabajo/implementacion-v3/mediciones.json lint ━━━━━━━━━━━━━━━━━━━━━━━━
i The size of the file is 2.5 MiB, which exceeds the configured maximum of 1.0 MiB for this project.
Use the `files.maxSize` configuration to change the maximum size of files processed, or `files.includes` to ignore the file.
modules/companies/src/api/application/person-photo.use-cases.ts:33:9 lint/complexity/useSimplifiedLogicExpression FIXABLE ━━━━━━━━━━
i Logical expression contains unnecessary complexity.
32 │ async save(companyId: string, personId: string, data: Uint8Array) {
> 33 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
34 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
i Safe fix: Reduce the complexity of the logical expression.
31 31 │
32 32 │ async save(companyId: string, personId: string, data: Uint8Array) {
33 │ - ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)
33 │ + ····if·(!(z.uuid().safeParse(companyId).success·&&·z.uuid().safeParse(personId).success))
34 34 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
35 35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
modules/companies/src/api/application/person-photo.use-cases.ts:49:9 lint/complexity/useSimplifiedLogicExpression FIXABLE ━━━━━━━━━━
i Logical expression contains unnecessary complexity.
48 │ async remove(companyId: string, personId: string) {
> 49 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
50 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
51 │
i Safe fix: Reduce the complexity of the logical expression.
47 47 │
48 48 │ async remove(companyId: string, personId: string) {
49 │ - ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)
49 │ + ····if·(!(z.uuid().safeParse(companyId).success·&&·z.uuid().safeParse(personId).success))
50 50 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
51 51 │
.agents/skills/shadcn/assets/showcase/color-pair.tsx:81:17 lint/style/noNegationElse FIXABLE ━━━━━━━━━━
! Invert blocks when performing a negation test.
79 │ }, [])
80 │
> 81 │ const level = !info
│ ^^^^^
> 82 │ ? ""
...
> 88 │ ? "AA Large"
> 89 │ : "Fail"
│ ^^^^^^^^
90 │
91 │ return (
i Safe fix: Invert the condition and the blocks.
79 79 │ }, [])
80 80 │
81 │ - ··const·level·=·!info
82 │ - ····?·""
83 │ - ····:·info.ratio·>=·7
81 │ + ··const·level·=·info
82 │ + ····?·info.ratio·>=·7
84 83 │ ? "AAA"
85 84 │ : info.ratio >= 4.5
······· │
87 86 │ : info.ratio >= 3
88 87 │ ? "AA Large"
89 │ - ··········:·"Fail"
88 │ + ··········:·"Fail"
89 │ + ····:·""
90 90 │
91 91 │ return (
.agents/skills/shadcn/assets/showcase/state-matrix.tsx:1:8 lint/style/useImportType FIXABLE ━━━━━━━━━━
× All these imports are only used as types.
> 1 │ import * as React from "react"
│ ^^^^^^^^^^^^^^^^^^^^^^^
2 │
3 │ import { cn } from "@/lib/utils"
i Importing the types with import type ensures that they are removed by the compilers and avoids loading unnecessary modules.
i Safe fix: Use import type.
1 │ import·type·*·as·React·from·"react"
│ +++++
.artifacts/account-deletion/cleanup-test.mts:3:1 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━━
× Block statements are preferred in this position.
1 │ import { createDatabase, readDatabaseEnvironment } from '../../apps/server/src/config/database';
2 │ const env=readDatabaseEnvironment(process.env);
> 3 │ if(env.DB_NAME!=='metis_desk_test'||env.NODE_ENV!=='test')throw Error('Solo pruebas');
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 │ const db=createDatabase(env);
5 │ const company='01a17cae-4bba-7070-a394-13f9009c5cfb';
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
3 │ if(env.DB_NAME!=='metis_desk_test'||env.NODE_ENV!=='test')·{·throw·Error('Solo·pruebas');·}
│ +++ ++
.artifacts/account-deletion/cleanup-test.mts:11:2 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
9 │ const rows=await db.query('SELECT i.kind,i.id FROM access_items i JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company',{replacements,transaction,type:'SELECT'});
10 │ console.info({fixtureCompany:company,items:rows});
> 11 │ for(const table of ['access_references','access_person_references']) await db.query(`DELETE r FROM ${table} r JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,{replacements,transaction});
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12 │ await db.query('DELETE r FROM access_revisions r JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company',{replacements,transaction});
13 │ for(const table of ['access_account_values','access_system_values']) await db.query(`DELETE v FROM ${table} v JOIN access_items i ON i.id=v.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,{replacements,transaction});
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
11 │ ·for(const·table·of·['access_references','access_person_references'])·{·await·db.query(`DELETE·r·FROM·${table}·r·JOIN·access_items·i·ON·i.id=r.itemId·JOIN·access_workspaces·w·ON·w.id=i.workspaceId·WHERE·w.companyId=:company`,{replacements,transaction});·}
│ ++ ++
.artifacts/account-deletion/cleanup-test.mts:13:2 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
11 │ for(const table of ['access_references','access_person_references']) await db.query(`DELETE r FROM ${table} r JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,{replacements,transaction});
12 │ await db.query('DELETE r FROM access_revisions r JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company',{replacements,transaction});
> 13 │ for(const table of ['access_account_values','access_system_values']) await db.query(`DELETE v FROM ${table} v JOIN access_items i ON i.id=v.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`,{replacements,transaction});
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
14 │ await db.query('DELETE i FROM access_items i JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company',{replacements,transaction});
15 │ await db.query('DELETE FROM access_workspaces WHERE companyId=:company',{replacements,transaction});
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
13 │ ·for(const·table·of·['access_account_values','access_system_values'])·{·await·db.query(`DELETE·v·FROM·${table}·v·JOIN·access_items·i·ON·i.id=v.ownerId·JOIN·access_workspaces·w·ON·w.id=i.workspaceId·WHERE·w.companyId=:company`,{replacements,transaction});·}
│ ++ ++
modules/companies/src/api/application/person-photo.use-cases.ts:25:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
24 │ async get(personId: string) {
> 25 │ if (!z.uuid().safeParse(personId).success)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 26 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
27 │ const photo = await this.repository.get(personId);
28 │
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
23 23 │
24 24 │ async get(personId: string) {
25 │ - ····if·(!z.uuid().safeParse(personId).success)
26 │ - ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
25 │ + ····if·(!z.uuid().safeParse(personId).success)·{
26 │ + ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
27 │ + ····}
27 28 │ const photo = await this.repository.get(personId);
28 29 │
modules/companies/src/api/application/person-photo.use-cases.ts:33:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
32 │ async save(companyId: string, personId: string, data: Uint8Array) {
> 33 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 34 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
36 │ return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
31 31 │
32 32 │ async save(companyId: string, personId: string, data: Uint8Array) {
33 │ - ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)
34 │ - ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
33 │ + ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)·{
34 │ + ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
35 │ + ····}
35 36 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
36 37 │ return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
modules/companies/src/api/application/person-photo.use-cases.ts:35:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
33 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
34 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
> 35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 36 │ return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
37 │ if (!(await this.repository.exists(companyId, personId)))
38 │ return Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
33 33 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
34 34 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
35 │ - ····if·(data.length·>·PERSON_PHOTO_LIMITS.inputBytes)
36 │ - ······return·Result.fail(new·PersonPhotoError("PHOTO_TOO_LARGE"));
35 │ + ····if·(data.length·>·PERSON_PHOTO_LIMITS.inputBytes)·{
36 │ + ······return·Result.fail(new·PersonPhotoError("PHOTO_TOO_LARGE"));
37 │ + ····}
37 38 │ if (!(await this.repository.exists(companyId, personId)))
38 39 │ return Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
modules/companies/src/api/application/person-photo.use-cases.ts:37:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
36 │ return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
> 37 │ if (!(await this.repository.exists(companyId, personId)))
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 38 │ return Result.fail(new PersonPhotoError("PERSON_NOT_FOUND"));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 │ const processed = await this.processor.optimize(data);
40 │
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
35 35 │ if (data.length > PERSON_PHOTO_LIMITS.inputBytes)
36 36 │ return Result.fail(new PersonPhotoError("PHOTO_TOO_LARGE"));
37 │ - ····if·(!(await·this.repository.exists(companyId,·personId)))
38 │ - ······return·Result.fail(new·PersonPhotoError("PERSON_NOT_FOUND"));
37 │ + ····if·(!(await·this.repository.exists(companyId,·personId)))·{
38 │ + ······return·Result.fail(new·PersonPhotoError("PERSON_NOT_FOUND"));
39 │ + ····}
39 40 │ const processed = await this.processor.optimize(data);
40 41 │
modules/companies/src/api/application/person-photo.use-cases.ts:41:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
39 │ const processed = await this.processor.optimize(data);
40 │
> 41 │ if (!processed.isSuccess) return Result.fail(processed.error);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
42 │
43 │ return (await this.repository.replace(companyId, personId, processed.data))
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
41 │ ····if·(!processed.isSuccess)·{·return·Result.fail(processed.error);·}
│ ++ ++
modules/companies/src/api/application/person-photo.use-cases.ts:49:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
48 │ async remove(companyId: string, personId: string) {
> 49 │ if (!z.uuid().safeParse(companyId).success || !z.uuid().safeParse(personId).success)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 50 │ return Result.fail(new PersonPhotoError("INVALID_REQUEST"));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
51 │
52 │ return (await this.repository.replace(companyId, personId, null))
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
47 47 │
48 48 │ async remove(companyId: string, personId: string) {
49 │ - ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)
50 │ - ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
49 │ + ····if·(!z.uuid().safeParse(companyId).success·||·!z.uuid().safeParse(personId).success)·{
50 │ + ······return·Result.fail(new·PersonPhotoError("INVALID_REQUEST"));
51 │ + ····}
51 52 │
52 53 │ return (await this.repository.replace(companyId, personId, null))
modules/companies/src/api/application/process.use-cases.ts:127:5 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
125 │ const process = UniqueID.create(id);
126 │
> 127 │ if (!(company.isSuccess && process.isSuccess))
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> 128 │ return Promise.resolve(Result.fail(new ProcessError("INVALID_REQUEST")));
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
129 │
130 │ return this.repository.remove(company.data, process.data);
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
125 125 │ const process = UniqueID.create(id);
126 126 │
127 │ - ····if·(!(company.isSuccess·&&·process.isSuccess))
128 │ - ······return·Promise.resolve(Result.fail(new·ProcessError("INVALID_REQUEST")));
127 │ + ····if·(!(company.isSuccess·&&·process.isSuccess))·{
128 │ + ······return·Promise.resolve(Result.fail(new·ProcessError("INVALID_REQUEST")));
129 │ + ····}
129 130 │
130 131 │ return this.repository.remove(company.data, process.data);
modules/companies/src/api/infrastructure/persistence/migrate-people.ts:11:3 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
9 │ const columns = await query.describeTable("company_contacts");
10 │
> 11 │ if (!columns.photoVersion)
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
> 12 │ await query.addColumn("company_contacts", "photoVersion", {
> 13 │ type: DataTypes.STRING(64),
> 14 │ allowNull: true,
> 15 │ });
│ ^^^
16 │ for (const [name, length] of [
17 │ ["position", 100],
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
9 9 │ const columns = await query.describeTable("company_contacts");
10 10 │
11 │ - ··if·(!columns.photoVersion)
11 │ + ··if·(!columns.photoVersion)·{
12 12 │ await query.addColumn("company_contacts", "photoVersion", {
13 13 │ type: DataTypes.STRING(64),
14 14 │ allowNull: true,
15 │ - ····});
15 │ + ····});
16 │ + ··}
16 17 │ for (const [name, length] of [
17 18 │ ["position", 100],
modules/companies/src/api/infrastructure/persistence/person-photo-migration.ts:10:3 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
8 │ );
9 │
> 10 │ if (rows.some((row) => row.name === "person_photos")) return;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
11 │ await database
12 │ .getQueryInterface()
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
10 │ ··if·(rows.some((row)·=>·row.name·===·"person_photos"))·{·return;·}
│ ++ ++
modules/companies/src/api/infrastructure/persistence/sequelize-person-photo.repository.ts:49:7 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
47 │ });
48 │
> 49 │ if (!person) return false;
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
50 │ if (photo)
51 │ await PersonPhotoModel.upsert(
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
49 │ ······if·(!person)·{·return·false;·}
│ ++ ++
modules/companies/src/api/infrastructure/persistence/sequelize-person-photo.repository.ts:50:7 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
49 │ if (!person) return false;
> 50 │ if (photo)
│ ^^^^^^^^^^
> 51 │ await PersonPhotoModel.upsert(
> 52 │ { personId, companyId, data: Buffer.from(photo.data), version: photo.version },
> 53 │ { transaction }
> 54 │ );
> 55 │ else await PersonPhotoModel.destroy({ where: { personId }, transaction });
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56 │ await person.update({ photoVersion: photo?.version ?? null }, { transaction });
57 │
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
48 48 │
49 49 │ if (!person) return false;
50 │ - ······if·(photo)
50 │ + ······if·(photo)·{
51 51 │ await PersonPhotoModel.upsert(
52 52 │ { personId, companyId, data: Buffer.from(photo.data), version: photo.version },
53 53 │ { transaction }
54 │ - ········);
54 │ + ········);
55 │ + ······}
55 56 │ else await PersonPhotoModel.destroy({ where: { personId }, transaction });
56 57 │ await person.update({ photoVersion: photo?.version ?? null }, { transaction });
modules/companies/src/api/infrastructure/persistence/sequelize-person-photo.repository.ts:55:7 lint/style/useBlockStatements FIXABLE ━━━━━━━━━━
× Block statements are preferred in this position.
53 │ { transaction }
54 │ );
> 55 │ else await PersonPhotoModel.destroy({ where: { personId }, transaction });
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
56 │ await person.update({ photoVersion: photo?.version ?? null }, { transaction });
57 │
i Unsafe fix: Wrap the statement with a `JsBlockStatement`
55 │ ······else·{·await·PersonPhotoModel.destroy({·where:·{·personId·},·transaction·});·}
│ ++ ++
The number of diagnostics exceeds the limit allowed. Use --max-diagnostics to increase it.
Diagnostics not shown: 5.
Checked 2283 files in 1921ms. No fixes applied.
Found 18 errors.
Found 2 warnings.
Found 5 infos.
lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Some errors were emitted while running checks.
[ELIFECYCLE] Command failed with exit code 1.