import type { RelationshipContext, RelationshipReadAccess } from "@metis/relationship-contracts"; import { Result } from "@repo/rdx-utils"; import type { Sequelize } from "sequelize"; import { QueryTypes } from "sequelize"; import type { z } from "zod/v4"; import type { NetworkShareOptionsQuerySchema } from "../../../common/network-shares"; import { NetworkShareOptionsSchema } from "../../../common/network-shares"; /** Selección SMB estructurada y paginada, sin descargar recursos o revisiones de la compañía. */ export class NetworkShareOptions { constructor( private readonly database: Sequelize, private readonly access: RelationshipReadAccess ) {} async list(query: z.infer, context: RelationshipContext) { const allowed = await this.access.authorize(context); if (!allowed.isSuccess) { return allowed; } const rows = await this.database.query<{ id: string; name: string; address: string }>( `SELECT r.id,r.name,c.textValue AS address FROM resources r JOIN resource_network_shares s ON s.resourceId=r.id AND s.companyId=r.companyId JOIN resource_characteristics c ON c.resourceId=r.id JOIN resource_definitions f ON f.id=c.fieldId AND f.stockKey='field:unc' WHERE r.companyId=:companyId AND r.active=1 AND (:search = '' OR LOCATE(:search,r.name)>0 OR LOCATE(:search,c.textValue)>0) AND (:cursor IS NULL OR r.id>:cursor) ORDER BY r.id LIMIT 21`, { replacements: { companyId: context.companyId, search: query.search, cursor: query.cursor ?? null, }, type: QueryTypes.SELECT, } ); const items = rows.slice(0, 20); return Result.ok( NetworkShareOptionsSchema.parse({ items, nextCursor: rows.length > 20 ? items.at(-1)?.id : null, }) ); } }