refactor(shared): move upload/ into infrastructure/domain/application (RB-24)
libs/shared/src/upload/ held a network adapter, an Elm machine, and two application-layer coordinators outside the folder-per-layer convention every other context follows. The dependency-cruiser rule carved an exception around the misplaced adapter instead of the violation being fixed. Move all five files to the layer each belongs to (git mv), update every import across 24 consumer files, then delete the carve-out clause from .dependency-cruiser.base.js. No export renamed, no file split, no spec content changed. Deleting the carve-out exposed a second, pre-existing rule violation: ui-not-infrastructure had never fired against upload.adapter.ts because its old path did not match /infrastructure/. Three UI components injected UploadAdapter directly for its one-line contentUrl() wrapper. Route each through the existing pure uploadContentUrl() function via the application layer (upload-controller's new previewUrlFor, OrgTemplateStore's new previewUrlFor) instead — the same idiom brief.store.ts already used. npm run ci passes; dep:check is clean for both apps with the carve-out gone. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+17
-2
@@ -1,9 +1,19 @@
|
||||
import { DestroyRef, effect, inject } from '@angular/core';
|
||||
import { CategoryParams, UploadAdapter } from './upload.adapter';
|
||||
import {
|
||||
CategoryParams,
|
||||
UploadAdapter,
|
||||
uploadContentUrl,
|
||||
} from '@shared/infrastructure/upload.adapter';
|
||||
import { UploadShellService } from './upload-shell.service';
|
||||
import { problemDetail } from '@shared/infrastructure/api-error';
|
||||
import { SUBMIT_FAILED } from '@shared/application/submit';
|
||||
import { DeliveryChannel, UploadMsg, UploadState, inFlight, rejectReason } from './upload.machine';
|
||||
import {
|
||||
DeliveryChannel,
|
||||
UploadMsg,
|
||||
UploadState,
|
||||
inFlight,
|
||||
rejectReason,
|
||||
} from '@shared/domain/upload.machine';
|
||||
|
||||
export interface UploadControllerDeps {
|
||||
wizardId: string;
|
||||
@@ -59,6 +69,11 @@ export function createUploadController(deps: UploadControllerDeps) {
|
||||
}
|
||||
|
||||
return {
|
||||
/** Preview/download link for a completed upload; the dev-simulation `demo-*` ids
|
||||
have no stored bytes, so they get no link. */
|
||||
previewUrlFor(documentId: string): string | undefined {
|
||||
return documentId.startsWith('demo-') ? undefined : uploadContentUrl(documentId);
|
||||
},
|
||||
onFileSelected(categoryId: string, selected: File[]) {
|
||||
const cat = deps.getUpload().categories.find((c) => c.categoryId === categoryId);
|
||||
if (!cat) return;
|
||||
+7
-2
@@ -1,7 +1,12 @@
|
||||
import { Injectable, inject } from '@angular/core';
|
||||
import { UploadAdapter, XhrUploadRequest, XhrUploadHandle, UPLOAD_ABORTED } from './upload.adapter';
|
||||
import {
|
||||
UploadAdapter,
|
||||
XhrUploadRequest,
|
||||
XhrUploadHandle,
|
||||
UPLOAD_ABORTED,
|
||||
} from '@shared/infrastructure/upload.adapter';
|
||||
import { problemDetail } from '@shared/infrastructure/api-error';
|
||||
import { UploadMsg, Upload } from './upload.machine';
|
||||
import { UploadMsg, Upload } from '@shared/domain/upload.machine';
|
||||
|
||||
/**
|
||||
* Transport seam (PRD §6): how upload bytes leave the browser. The shipped impl is
|
||||
+1
-1
@@ -8,7 +8,7 @@ import { problemDetail } from '@shared/infrastructure/api-error';
|
||||
import { currentScenario } from '@shared/infrastructure/scenario';
|
||||
import { currentSubject } from '@shared/infrastructure/subject';
|
||||
import { environment } from '@shared/environments/environment';
|
||||
import { DocumentCategory } from './upload.machine';
|
||||
import { DocumentCategory } from '@shared/domain/upload.machine';
|
||||
|
||||
/** Answer-derived query params that affect which categories the server presents. */
|
||||
export interface CategoryParams {
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { Component, input, output } from '@angular/core';
|
||||
import type { DeliveryChannel } from '@shared/upload/upload.machine';
|
||||
import type { DeliveryChannel } from '@shared/domain/upload.machine';
|
||||
|
||||
/** Atom: choose how a document is delivered — uploaded digitally or sent by post.
|
||||
Thin wrapper over the Utrecht/RHC radio CSS. Pure UI: emits the chosen channel. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, computed, input, output } from '@angular/core';
|
||||
import type { DeliveryChannel, DocumentCategory, Upload } from '@shared/upload/upload.machine';
|
||||
import type { DeliveryChannel, DocumentCategory, Upload } from '@shared/domain/upload.machine';
|
||||
import { DeliveryChannelToggleComponent } from '../delivery-channel-toggle/delivery-channel-toggle.component';
|
||||
import { FileInputComponent } from '../file-input/file-input.component';
|
||||
import { SingleUploadComponent } from '../single-upload/single-upload.component';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import type { DocumentCategory, Upload } from '@shared/upload/upload.machine';
|
||||
import type { DocumentCategory, Upload } from '@shared/domain/upload.machine';
|
||||
import { DocumentCategoryComponent } from './document-category.component';
|
||||
|
||||
const meta: Meta<DocumentCategoryComponent> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, computed, input } from '@angular/core';
|
||||
import type { UploadStatus } from '@shared/upload/upload.machine';
|
||||
import type { UploadStatus } from '@shared/domain/upload.machine';
|
||||
import { UploadStatusIconComponent } from '../upload-status-icon/upload-status-icon.component';
|
||||
|
||||
const STATUS_LABELS: Record<UploadStatus['type'], string> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import type { UploadStatus } from '@shared/upload/upload.machine';
|
||||
import type { UploadStatus } from '@shared/domain/upload.machine';
|
||||
import { DocumentChipComponent } from './document-chip.component';
|
||||
|
||||
const meta: Meta<DocumentChipComponent> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, input, output } from '@angular/core';
|
||||
import type { DeliveryChannel, UploadState } from '@shared/upload/upload.machine';
|
||||
import type { DeliveryChannel, UploadState } from '@shared/domain/upload.machine';
|
||||
import { AlertComponent } from '@shared/ui/alert/alert.component';
|
||||
import { DocumentCategoryComponent } from '../document-category/document-category.component';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import type { UploadState } from '@shared/upload/upload.machine';
|
||||
import type { UploadState } from '@shared/domain/upload.machine';
|
||||
import { DocumentUploadComponent } from './document-upload.component';
|
||||
|
||||
const meta: Meta<DocumentUploadComponent> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, computed, input, output } from '@angular/core';
|
||||
import type { Upload } from '@shared/upload/upload.machine';
|
||||
import type { Upload } from '@shared/domain/upload.machine';
|
||||
import { DocumentChipComponent } from '../document-chip/document-chip.component';
|
||||
import { UploadProgressBarComponent } from '../upload-progress-bar/upload-progress-bar.component';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Meta, StoryObj } from '@storybook/angular';
|
||||
import type { Upload } from '@shared/upload/upload.machine';
|
||||
import type { Upload } from '@shared/domain/upload.machine';
|
||||
import { SingleUploadComponent } from './single-upload.component';
|
||||
|
||||
const meta: Meta<SingleUploadComponent> = {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Component, computed, input } from '@angular/core';
|
||||
import type { UploadStatus } from '@shared/upload/upload.machine';
|
||||
import type { UploadStatus } from '@shared/domain/upload.machine';
|
||||
|
||||
interface Glyph {
|
||||
char: string;
|
||||
|
||||
Reference in New Issue
Block a user