fix(field): repair finding creation and simplify mobile UX
Android CI / RC / Android · lint, tests, debug APK, release compile (push) Successful in 3m17s
DH V2 CI / API · typecheck, tests, build (push) Successful in 35s
DH V2 CI / WEB · typecheck, build (push) Successful in 20s
Production dependency audit / API · production dependencies (push) Successful in 9s
Production dependency audit / WEB · production dependencies (push) Successful in 9s
DH V2 CI / Docker / scripts contract (push) Successful in 1m7s
Android CI / RC / Android · lint, tests, debug APK, release compile (push) Successful in 3m17s
DH V2 CI / API · typecheck, tests, build (push) Successful in 35s
DH V2 CI / WEB · typecheck, build (push) Successful in 20s
Production dependency audit / API · production dependencies (push) Successful in 9s
Production dependency audit / WEB · production dependencies (push) Successful in 9s
DH V2 CI / Docker / scripts contract (push) Successful in 1m7s
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "dhv2-api",
|
||||
"version": "0.29.0-4",
|
||||
"version": "0.29.0-5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "dhv2-api",
|
||||
"version": "0.29.0-4",
|
||||
"version": "0.29.0-5",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@nestjs/common": "^11.0.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dhv2-api",
|
||||
"version": "0.29.0-4",
|
||||
"version": "0.29.0-5",
|
||||
"private": true,
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* F4 cambió el código visible del Acta a ACT-NNNNN-DD-MM-YY, pero el CHECK
|
||||
* histórico de Hallazgos seguía aceptando sólo ACTA-YYYY-NNNNNN-HNNN.
|
||||
* El servicio genera el Hallazgo a partir del código real del Acta, por lo que
|
||||
* PostgreSQL rechazaba altas válidas de campo con un 500.
|
||||
*/
|
||||
export class F65FieldFindingCodeContract1790121000000 implements MigrationInterface {
|
||||
name = 'F65FieldFindingCodeContract1790121000000';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE inspection_findings
|
||||
DROP CONSTRAINT IF EXISTS chk_inspection_findings_code
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE inspection_findings
|
||||
ADD CONSTRAINT chk_inspection_findings_code CHECK (
|
||||
code ~ '^(ACTA-[0-9]{4}-[0-9]{6}|ACT-[0-9]{5}-[0-9]{2}-[0-9]{2}-[0-9]{2})-H[0-9]{3}$'
|
||||
)
|
||||
`);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(`
|
||||
UPDATE inspection_findings finding
|
||||
SET code = 'ACTA-' || act.act_year::text || '-' || LPAD(act.act_number::text, 6, '0')
|
||||
|| '-H' || LPAD(finding.finding_number::text, 3, '0')
|
||||
FROM inspection_acts act
|
||||
WHERE finding.act_id = act.id
|
||||
AND finding.code ~ '^ACT-[0-9]{5}-[0-9]{2}-[0-9]{2}-[0-9]{2}-H[0-9]{3}$'
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE inspection_findings
|
||||
DROP CONSTRAINT IF EXISTS chk_inspection_findings_code
|
||||
`);
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE inspection_findings
|
||||
ADD CONSTRAINT chk_inspection_findings_code CHECK (
|
||||
code ~ '^ACTA-[0-9]{4}-[0-9]{6}-H[0-9]{3}$'
|
||||
)
|
||||
`);
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
IsOptional,
|
||||
IsString,
|
||||
IsUUID,
|
||||
Matches,
|
||||
Max,
|
||||
MaxLength,
|
||||
Min,
|
||||
@@ -56,8 +55,4 @@ export class CreateFieldFindingDto {
|
||||
@Max(10)
|
||||
severity?: number;
|
||||
|
||||
@IsOptional()
|
||||
@Transform(optionalText)
|
||||
@Matches(/^\d{4}-\d{2}-\d{2}$/)
|
||||
correctionDueOn?: string | null;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ export class FieldFindingsService {
|
||||
customLegalBasis: dto.customLegalBasis ?? null,
|
||||
description: dto.description,
|
||||
severity: dto.severity,
|
||||
correctionDueOn: dto.correctionDueOn ?? null,
|
||||
correctionDueOn: null,
|
||||
};
|
||||
const finding = await this.findings.create(act.id, payload, principal, request);
|
||||
return {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export const API_VERSION = '0.29.0-4';
|
||||
export const API_VERSION = '0.29.0-5';
|
||||
export const API_PHASE = 'F6.2';
|
||||
|
||||
@@ -8,5 +8,5 @@ test('health metadata reports the current F6.1 release', () => {
|
||||
assert.equal(API_PHASE, 'F6.2');
|
||||
const pkg = JSON.parse(readFileSync(resolve(process.cwd(), 'package.json'), 'utf8')) as { version: string };
|
||||
assert.equal(API_VERSION, pkg.version);
|
||||
assert.equal(API_VERSION, '0.29.0-4');
|
||||
assert.equal(API_VERSION, '0.29.0-5');
|
||||
});
|
||||
@@ -10,8 +10,8 @@ function mountedRepoFile(path: string): string {
|
||||
test('F6.3 Android test cut targets production API and has a distinct installable debug version', () => {
|
||||
const gradle = mountedRepoFile('android-app/app/build.gradle.kts');
|
||||
|
||||
assert.match(gradle, /versionCode = 34/);
|
||||
assert.match(gradle, /versionName = "0\.19\.6"/);
|
||||
assert.match(gradle, /versionCode = 35/);
|
||||
assert.match(gradle, /versionName = "0\.19\.7"/);
|
||||
assert.match(gradle, /https:\/\/dhv2\.korexlabs\.com\/api\/v3\//);
|
||||
assert.match(gradle, /applicationIdSuffix = "\.debug"/);
|
||||
});
|
||||
|
||||
@@ -31,7 +31,8 @@ test('F6.1 uses contextual type catalog for Yacimiento and keeps OTROS/add-anoth
|
||||
assert.match(catalog, /finding_catalog_asset_overrides override/);
|
||||
assert.match(resolver, /code: 'OTHER'/);
|
||||
assert.match(resolver, /label: 'OTROS'/);
|
||||
assert.match(androidFinding, /OTROS · No está en el catálogo/);
|
||||
assert.match(androidFinding, /ExposedDropdownMenuBox/);
|
||||
assert.match(androidFinding, /Otro \/ No está en la lista/);
|
||||
assert.match(androidFinding, /También podés registrar otro Hallazgo sobre el mismo Inventario/);
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
import test from 'node:test';
|
||||
|
||||
function source(path: string): string {
|
||||
return readFileSync(resolve(process.cwd(), path), 'utf8');
|
||||
}
|
||||
|
||||
test('F6.5 finding code CHECK accepts the current visible Acta code', () => {
|
||||
const migration = source('src/database/migrations/1790121000000-f6-5-field-finding-code-contract.ts');
|
||||
const service = source('src/inspection-findings/inspection-findings.service.ts');
|
||||
|
||||
assert.match(migration, /ACT-\[0-9\]\{5\}-\[0-9\]\{2\}-\[0-9\]\{2\}-\[0-9\]\{2\}/);
|
||||
assert.match(migration, /-H\[0-9\]\{3\}/);
|
||||
assert.match(service, /code: `\$\{act\.code\}-H\$\{String\(findingNumber\)\.padStart\(3, '0'\)\}`/);
|
||||
});
|
||||
|
||||
test('F6.5 mobile finding creation never asks the inspector for a correction date', () => {
|
||||
const dto = source('src/inspection-visits/dto/create-field-finding.dto.ts');
|
||||
const adapter = source('src/inspection-visits/field-findings.service.ts');
|
||||
const androidRequest = source('../android-app/app/src/main/java/com/korexlabs/dhinspeccion/data/FieldFindingsMobile.kt');
|
||||
const androidScreen = source('../android-app/app/src/main/java/com/korexlabs/dhinspeccion/ui/FieldFindingScreen.kt');
|
||||
|
||||
assert.doesNotMatch(dto, /correctionDueOn/);
|
||||
assert.match(adapter, /correctionDueOn: null/);
|
||||
assert.doesNotMatch(androidRequest.match(/data class CreateFieldFindingRequest\([\s\S]*?\n\)/)?.[0] ?? '', /correctionDueOn/);
|
||||
assert.doesNotMatch(androidScreen, /Fecha de corrección/);
|
||||
assert.match(androidScreen, /ExposedDropdownMenuBox/);
|
||||
assert.match(androidScreen, /Tipo de Hallazgo \*/);
|
||||
});
|
||||
Reference in New Issue
Block a user