@aiquants/daily-report 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -1
- package/dist/server.d.mts +84 -16
- package/dist/server.d.ts +84 -16
- package/dist/server.js +10 -10
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +10 -10
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client/streaming/daily-report-ids-stream-client.spec.ts +25 -15
- package/src/server/handlers.ts +94 -12
- package/src/server/handlers.visibility.spec.ts +246 -0
- package/src/server/ports.ts +30 -3
- package/src/server/service.spec.ts +161 -1
- package/src/server/service.ts +67 -21
- package/src/server/test-helpers/handlers-config.ts +20 -1
- package/src/server/visibility.spec.ts +135 -0
- package/src/server/visibility.ts +107 -18
package/dist/server.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
"use strict";var je=Object.defineProperty;var Vt=Object.getOwnPropertyDescriptor;var jt=Object.getOwnPropertyNames;var Jt=Object.prototype.hasOwnProperty;var mt=t=>{throw TypeError(t)};var Gt=(t,e)=>{for(var r in e)je(t,r,{get:e[r],enumerable:!0})},Qt=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let m of jt(e))!Jt.call(t,m)&&m!==r&&je(t,m,{get:()=>e[m],enumerable:!(s=Vt(e,m))||s.enumerable});return t};var Xt=t=>Qt(je({},"__esModule",{value:!0}),t);var yt=(t,e,r)=>e.has(t)||mt("Cannot "+r);var Je=(t,e,r)=>(yt(t,e,"read from private field"),r?r.call(t):e.get(t)),ht=(t,e,r)=>e.has(t)?mt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),ft=(t,e,r,s)=>(yt(t,e,"write to private field"),s?s.call(t,r):e.set(t,r),r);var Br={};Gt(Br,{DailyReportSseReader:()=>ke,DailyReportViewerScope:()=>ce,SqlResultCache:()=>xe,asciiFallbackFileName:()=>xt,buildVisibleSourceTypeCondition:()=>at,computeSourceTypeDigest:()=>Tt,computeViewerScopeDigest:()=>Ce,createDailyReportHandlers:()=>it,createDailyReportServer:()=>Pr,createDailyReportService:()=>ot,createEpochStore:()=>Ge,defineDailyReportAuthzResources:()=>kt,defineDailyReportSchema:()=>$r,deniesEverySourceType:()=>fe,encodeRfc8187:()=>Et,formatDateValue:()=>te,generateETag:()=>Ye,isSourceTypeVisible:()=>ye,isStreamIdLte:()=>Ne,jsonResponseWithETag:()=>de,normalizeVisibleSourceTypes:()=>At,sanitizeMediaType:()=>st,seedDailyReportAuthzResources:()=>kr,transformJsonArray:()=>Lr});module.exports=Xt(Br);var Ge=t=>({async getEpoch(e){try{let r=await t?.getClient();if(!r)return 0;let s=await r.get(e);return s?Number(s):0}catch{return 0}},async incrementEpoch(e){try{let r=await t?.getClient();if(!r)return;await r.incr(e)}catch{}}}),xe=class{constructor(e,r){this.config=e;this.epochStore=r;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.maybeRefreshAhead=e=>{let r=e.refreshAheadRatio;if(r===void 0)return;let{cacheKey:s}=e,m=this.buckets.get(s);if(!m)return;let c=e.ttlMsOverride??this.config.defaultTtlMs;if(c-(m.expireAt-Date.now())<c*r||this.inFlight.has(s))return;let y;y=(async()=>{let L=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0,u=await e.fetcher();return this.inFlight.get(s)===y&&this.buckets.set(s,{records:u,expireAt:Date.now()+c,epoch:L}),u})(),this.inFlight.set(s,y),y.catch(()=>{}).finally(()=>{this.inFlight.get(s)===y&&this.inFlight.delete(s)})};this.getOrFetch=async e=>{let{cacheKey:r,forceRefresh:s,snapshot:m}=e,c=this.buckets.get(r);if(s&&(this.buckets.delete(r),this.inFlight.delete(r)),!s&&c&&c.expireAt>Date.now())if(e.epochKey){let y=await this.epochStore.getEpoch(e.epochKey);if(c.epoch===y)return this.maybeRefreshAhead(e),m?c.records.map(L=>structuredClone(L)):c.records;this.buckets.delete(r)}else return this.maybeRefreshAhead(e),m?c.records.map(y=>structuredClone(y)):c.records;if(!s&&this.inFlight.has(r)){let y=await this.inFlight.get(r);return m?y.map(L=>structuredClone(L)):y}let A;A=(async()=>{let y=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0,L=await e.fetcher();if(s||this.inFlight.get(r)===A){let u=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs);this.buckets.set(r,{records:L,expireAt:u,epoch:y}),this.buckets.size>500&&this.cleanExpired()}return L})(),s||this.inFlight.set(r,A);try{let y=await A;return m?y.map(L=>structuredClone(L)):y}finally{this.inFlight.get(r)===A&&this.inFlight.delete(r)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let r of this.buckets.keys())r.startsWith(e)&&this.buckets.delete(r);for(let r of this.inFlight.keys())r.startsWith(e)&&this.inFlight.delete(r)}}cleanExpired(){let e=Date.now();for(let[r,s]of this.buckets.entries())s.expireAt<=e&&this.buckets.delete(r)}};var Wt=/^\d{4}-\d{2}-\d{2}$/,Zt=/^\d{4}\/\d{2}\/\d{2}$/,bt=t=>t<10?`0${t}`:`${t}`,gt=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),r=bt(t.getMonth()+1),s=bt(t.getDate());return`${e}-${r}-${s}`};var se=t=>{if(t==null)return null;if(t instanceof Date)return gt(t);let e=t.trim();if(e==="")return null;if(Wt.test(e))return e;if(Zt.test(e))return e.replaceAll("/","-");let r=new Date(e);return gt(r)};var er=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId;var Rt=(t,e)=>{let r=t.findIndex(s=>er({businessDate:s.businessDate,reportHubId:s.reportHubId},e)>0);return r===-1?t.length:r};var le=(t,e,r=console)=>{let s=m=>typeof m=="string"?[`${e} ${m}`]:[e,m];return{debug:(m,...c)=>{t<=0&&r.debug(...s(m),...c)},info:(m,...c)=>{t<=1&&r.info(...s(m),...c)},warn:(m,...c)=>{t<=2&&r.warn(...s(m),...c)},error:(m,...c)=>{t<=3&&r.error(...s(m),...c)}}};var d=require("zod"),tr=d.z.object({name:d.z.string().nullish(),affiliation:d.z.string().nullish()}),rr=d.z.object({name:d.z.string().nullish(),text:d.z.string().nullish(),color:d.z.string().nullish()}),nr=d.z.object({id:d.z.number(),name:d.z.string().nullish(),color:d.z.string().nullish()}),Dt=d.z.object({id:d.z.number(),userId:d.z.string().nullish(),userName:d.z.string().nullish(),content:d.z.string().nullish(),createdAt:d.z.string().nullish(),isMine:d.z.boolean()}),ar=d.z.object({id:d.z.string(),fileName:d.z.string(),fileType:d.z.string().nullable(),fileSize:d.z.number().nullable(),createdAt:d.z.string().nullable(),state:d.z.enum(["present","absent","unknown"])}),Qe=d.z.object({reportHubId:d.z.number(),date:d.z.string().nullish(),createdAt:d.z.string().nullish(),author:d.z.string().nullish(),userId:d.z.string().nullish(),sourceType:d.z.string().nullish(),employeeName:d.z.string().nullish(),updatedBy:d.z.string().nullish(),updatedAt:d.z.string().nullish(),category:d.z.string().nullish(),creationCategory:d.z.string().nullish(),visitTimeFrom:d.z.string().nullish(),visitTimeTo:d.z.string().nullish(),customerName:d.z.string().nullish(),interviewers:d.z.array(tr),subject:d.z.string().nullish(),content:d.z.string().nullish(),comments:d.z.array(rr),isRead:d.z.boolean(),isStarred:d.z.boolean(),labels:d.z.array(nr),commentItems:d.z.array(Dt),attachments:d.z.array(ar).default([])}),sr=d.z.object({type:d.z.literal("connected")}),Oe=d.z.object({type:d.z.literal("status-update"),reportHubId:d.z.number(),statusType:d.z.enum(["star","read"]),value:d.z.boolean(),clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),Xe=d.z.string().optional(),We=d.z.object({type:d.z.literal("comment-add"),reportHubId:d.z.number(),comment:Dt,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional(),sourceType:Xe}),Ze=d.z.object({type:d.z.literal("comment-delete"),reportHubId:d.z.number(),commentId:d.z.number(),clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional(),sourceType:Xe}),et=d.z.object({type:d.z.literal("report-create"),reportHubId:d.z.number(),report:Qe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),tt=d.z.object({type:d.z.literal("report-update"),reportHubId:d.z.number(),report:Qe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),rt=d.z.object({type:d.z.literal("report-publish"),reportHubId:d.z.number(),report:Qe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),nt=d.z.object({type:d.z.literal("report-delete"),reportHubId:d.z.number(),clientTempId:d.z.string(),sourceType:Xe}),wt=d.z.discriminatedUnion("type",[sr,Oe,We,Ze,et,tt,rt,nt]);var St=require("crypto"),Ye=t=>{let e=JSON.stringify(t);return`"${(0,St.createHash)("sha256").update(e).digest("hex")}"`};var ir=le(1,"[Response]"),de=(t,e,r,s=200,m=ir)=>{let c=Ye(r),A=t.headers.get("If-None-Match");m.info(`[jsonResponseWithETag] ETag: ${c}, If-None-Match: ${A}`);let y=new Headers({"Content-Type":"application/json","Cache-Control":"private, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","Content-Security-Policy":"default-src 'none'",ETag:c});return e&&y.append("Set-Cookie",e),t.method==="GET"&&s===200&&A===c?new Response(null,{status:304,headers:y}):new Response(JSON.stringify(r),{status:s,headers:y})};var It=require("events");var Ne=(t,e)=>{let[r,s]=t.split("-").map(Number),[m,c]=e.split("-").map(Number);return r!==m?r<m:s<=c},ke=class{constructor(e){this.config=e;this._emitter=new It.EventEmitter;this._state="idle";this._refCount=0;this._lastId="$";this._emitter.setMaxListeners(0),this._logger=e.logger??le(1,"[SSE Reader]")}subscribe(e,r){return this._emitter.on("entry",e),r&&this._emitter.on("error",r),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),r&&this._emitter.removeListener("error",r),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="$"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"&&this._refCount!==0){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitError(e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitError(new Error("Failed to create Redis client for SSE reader"));return}if(this._client.on("error",e=>{this._logger.error("Redis client error:",e)}),this._lastId==="$")try{let e=await this.config.redis?.getClient();if(e){let r=await e.xRevRange(this.config.streamKey,"+","-",{COUNT:1});this._lastId=r.length>0?r[0].id:"0-0"}}catch(e){this._logger.warn("Failed to resolve stream tail anchor; falling back to $:",e)}try{for(;this._state==="running"&&this._client?.isOpen;){let e=await this._client.xRead([{key:this.config.streamKey,id:this._lastId}],{BLOCK:5e3,COUNT:100});if(e)for(let r of e)for(let s of r.messages){this._lastId=s.id;try{let m=s.message?.data?JSON.parse(s.message.data):null,c=m?.type;if((c==="report-create"||c==="report-delete"||c==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),c==="comment-add"||c==="comment-delete"||c==="status-update"){let A=m?.reportHubId;typeof A=="number"&&(this.config.cache.invalidate(`daily-report:detail:${A}`),this.config.cache.invalidatePrefix(`daily-report:detail:${A}:user:`))}}catch{}this._emitter.emit("entry",{id:s.id,message:s.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitError(e instanceof Error?e:new Error(String(e))))}finally{if(this._client?.isOpen)try{await this._client.quit()}catch{}this._client=void 0,this._state="idle",this._refCount>0&&this._startLoop()}}}async _stopLoop(){if(this._state==="running"){if(this._state="stopping",this._client?.isOpen)try{await this._client.quit()}catch{}for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50))}}_emitError(e){this._emitter.listenerCount("error")>0?this._emitter.emit("error",e):this._logger.error("SSE reader error (no error listeners):",e)}};var Le=require("drizzle-orm");var or="",lr=64,ur=t=>t.toLowerCase(),dr=t=>t.trim().toLowerCase();function At(t){if(t==null)return null;if(!Array.isArray(t))return new Set;let e=new Set;for(let r of t){if(typeof r!="string")continue;let s=dr(r);s.length>0&&e.add(s)}return e}function ye(t,e){return t===null?!0:e==null?!1:t.has(ur(e))}function fe(t){return t!==null&&t.size===0}function at(t,e){if(e!==null)return e.size===0?Le.sql`1 = 0`:(0,Le.inArray)(Le.sql`LOWER(${t})`,[...e])}var Te,qe=class qe{constructor(e){ht(this,Te);ft(this,Te,e)}get visible(){return Je(this,Te)===null?null:new Set(Je(this,Te))}static restrictTo(e){return new qe(At(e))}static unrestricted(e){return new qe(null)}};Te=new WeakMap;var ce=qe;function Ce(t){return Tt(t.visible)}function Tt(t){if(t===null)return"all";if(t.size===0)return"none";let e=[...t].sort().map(s=>`${s.length}:${s}`).join(or);if(e.length<=lr)return`s:${e}`;let r=2166136261;for(let s=0;s<e.length;s++)r^=e.charCodeAt(s),r=Math.imul(r,16777619);return`sh:${(r>>>0).toString(16)}`}var $=(t,e)=>new Response(JSON.stringify(t),{status:e?.status??200,headers:{"Content-Type":"application/json"}}),ze=200,Mt=4e3,cr="stream interrupted by server error",pr=/^\d{4}-\d{2}-\d{2}$/,mr=15e3,Ct=Symbol("ids-stream-heartbeat"),yr=12,hr=t=>{let e=t.searchParams.get("cursor_report_hub_id"),r=t.searchParams.get("cursor_business_date");if(e===null)return r===null?{cursor:null}:{invalid:!0};let s=Number.parseInt(e,10);return!Number.isSafeInteger(s)||String(s)!==e||s<=0?{invalid:!0}:r===null?{cursor:{businessDate:null,reportHubId:s}}:pr.test(r)?{cursor:{businessDate:r,reportHubId:s}}:{invalid:!0}};async function*_t(t,e,r=ze){let s=e?Rt(t,e):0,m=!0;for(;;){let c=t.slice(s,s+(m?r:Mt));s+=c.length;let A=s>=t.length,y=c[c.length-1];if(yield{items:c,nextCursor:A||!y?null:{businessDate:y.businessDate,reportHubId:y.reportHubId},isLast:A,...m?{total:t.length}:{}},m=!1,A)return}}var vt=(t,e,r,s)=>{let m=new TextEncoder,c=!1,A=null,y=new ReadableStream({async pull(u){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}let P=null;try{A===null&&(A=e.next());let p=new Promise(pe=>{P=setTimeout(()=>pe(Ct),mr)}),K=await Promise.race([A,p]);if(P!==null&&(clearTimeout(P),P=null),K===Ct){if(c||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(m.encode(`
|
|
2
|
-
`));return}
|
|
3
|
-
`))}catch(
|
|
4
|
-
`)),u.close()}catch{}}},cancel(){
|
|
1
|
+
"use strict";var We=Object.defineProperty;var Gt=Object.getOwnPropertyDescriptor;var Qt=Object.getOwnPropertyNames;var Xt=Object.prototype.hasOwnProperty;var Dt=t=>{throw TypeError(t)};var Wt=(t,e)=>{for(var r in e)We(t,r,{get:e[r],enumerable:!0})},Zt=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of Qt(e))!Xt.call(t,p)&&p!==r&&We(t,p,{get:()=>e[p],enumerable:!(a=Gt(e,p))||a.enumerable});return t};var er=t=>Zt(We({},"__esModule",{value:!0}),t);var wt=(t,e,r)=>e.has(t)||Dt("Cannot "+r);var $e=(t,e,r)=>(wt(t,e,"read from private field"),r?r.call(t):e.get(t)),Ze=(t,e,r)=>e.has(t)?Dt("Cannot add the same private member more than once"):e instanceof WeakSet?e.add(t):e.set(t,r),et=(t,e,r,a)=>(wt(t,e,"write to private field"),a?a.call(t,r):e.set(t,r),r);var Yr={};Wt(Yr,{DailyReportSseReader:()=>Be,DailyReportViewerScope:()=>ce,SqlResultCache:()=>Pe,asciiFallbackFileName:()=>Lt,buildVisibleSourceTypeCondition:()=>pt,computeSourceTypeDigest:()=>ct,computeViewerScopeDigest:()=>Me,createDailyReportHandlers:()=>yt,createDailyReportServer:()=>Or,createDailyReportService:()=>ht,createEpochStore:()=>tt,defineDailyReportAuthzResources:()=>$t,defineDailyReportSchema:()=>Hr,deniesEverySourceType:()=>Re,encodeRfc8187:()=>Nt,formatDateValue:()=>ne,generateETag:()=>Ve,isSourceTypeVisible:()=>he,isStreamIdLte:()=>Ce,jsonResponseWithETag:()=>de,normalizeVisibleSourceTypes:()=>dt,sanitizeMediaType:()=>mt,seedDailyReportAuthzResources:()=>Pr,transformJsonArray:()=>Ur});module.exports=er(Yr);var tt=t=>({async getEpoch(e){try{let r=await t?.getClient();if(!r)return 0;let a=await r.get(e);return a?Number(a):0}catch{return 0}},async incrementEpoch(e){try{let r=await t?.getClient();if(!r)return;await r.incr(e)}catch{}}}),Pe=class{constructor(e,r){this.config=e;this.epochStore=r;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.maybeRefreshAhead=e=>{let r=e.refreshAheadRatio;if(r===void 0)return;let{cacheKey:a}=e,p=this.buckets.get(a);if(!p)return;let m=e.ttlMsOverride??this.config.defaultTtlMs;if(m-(p.expireAt-Date.now())<m*r||this.inFlight.has(a))return;let h;h=(async()=>{let L=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0,u=await e.fetcher();return this.inFlight.get(a)===h&&this.buckets.set(a,{records:u,expireAt:Date.now()+m,epoch:L}),u})(),this.inFlight.set(a,h),h.catch(()=>{}).finally(()=>{this.inFlight.get(a)===h&&this.inFlight.delete(a)})};this.getOrFetch=async e=>{let{cacheKey:r,forceRefresh:a,snapshot:p}=e,m=this.buckets.get(r);if(a&&(this.buckets.delete(r),this.inFlight.delete(r)),!a&&m&&m.expireAt>Date.now())if(e.epochKey){let h=await this.epochStore.getEpoch(e.epochKey);if(m.epoch===h)return this.maybeRefreshAhead(e),p?m.records.map(L=>structuredClone(L)):m.records;this.buckets.delete(r)}else return this.maybeRefreshAhead(e),p?m.records.map(h=>structuredClone(h)):m.records;if(!a&&this.inFlight.has(r)){let h=await this.inFlight.get(r);return p?h.map(L=>structuredClone(L)):h}let S;S=(async()=>{let h=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0,L=await e.fetcher();if(a||this.inFlight.get(r)===S){let u=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs);this.buckets.set(r,{records:L,expireAt:u,epoch:h}),this.buckets.size>500&&this.cleanExpired()}return L})(),a||this.inFlight.set(r,S);try{let h=await S;return p?h.map(L=>structuredClone(L)):h}finally{this.inFlight.get(r)===S&&this.inFlight.delete(r)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let r of this.buckets.keys())r.startsWith(e)&&this.buckets.delete(r);for(let r of this.inFlight.keys())r.startsWith(e)&&this.inFlight.delete(r)}}cleanExpired(){let e=Date.now();for(let[r,a]of this.buckets.entries())a.expireAt<=e&&this.buckets.delete(r)}};var tr=/^\d{4}-\d{2}-\d{2}$/,rr=/^\d{4}\/\d{2}\/\d{2}$/,St=t=>t<10?`0${t}`:`${t}`,It=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),r=St(t.getMonth()+1),a=St(t.getDate());return`${e}-${r}-${a}`};var le=t=>{if(t==null)return null;if(t instanceof Date)return It(t);let e=t.trim();if(e==="")return null;if(tr.test(e))return e;if(rr.test(e))return e.replaceAll("/","-");let r=new Date(e);return It(r)};var nr=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId;var At=(t,e)=>{let r=t.findIndex(a=>nr({businessDate:a.businessDate,reportHubId:a.reportHubId},e)>0);return r===-1?t.length:r};var ue=(t,e,r=console)=>{let a=p=>typeof p=="string"?[`${e} ${p}`]:[e,p];return{debug:(p,...m)=>{t<=0&&r.debug(...a(p),...m)},info:(p,...m)=>{t<=1&&r.info(...a(p),...m)},warn:(p,...m)=>{t<=2&&r.warn(...a(p),...m)},error:(p,...m)=>{t<=3&&r.error(...a(p),...m)}}};var c=require("zod"),ar=c.z.object({name:c.z.string().nullish(),affiliation:c.z.string().nullish()}),ir=c.z.object({name:c.z.string().nullish(),text:c.z.string().nullish(),color:c.z.string().nullish()}),sr=c.z.object({id:c.z.number(),name:c.z.string().nullish(),color:c.z.string().nullish()}),Tt=c.z.object({id:c.z.number(),userId:c.z.string().nullish(),userName:c.z.string().nullish(),content:c.z.string().nullish(),createdAt:c.z.string().nullish(),isMine:c.z.boolean()}),or=c.z.object({id:c.z.string(),fileName:c.z.string(),fileType:c.z.string().nullable(),fileSize:c.z.number().nullable(),createdAt:c.z.string().nullable(),state:c.z.enum(["present","absent","unknown"])}),rt=c.z.object({reportHubId:c.z.number(),date:c.z.string().nullish(),createdAt:c.z.string().nullish(),author:c.z.string().nullish(),userId:c.z.string().nullish(),sourceType:c.z.string().nullish(),employeeName:c.z.string().nullish(),updatedBy:c.z.string().nullish(),updatedAt:c.z.string().nullish(),category:c.z.string().nullish(),creationCategory:c.z.string().nullish(),visitTimeFrom:c.z.string().nullish(),visitTimeTo:c.z.string().nullish(),customerName:c.z.string().nullish(),interviewers:c.z.array(ar),subject:c.z.string().nullish(),content:c.z.string().nullish(),comments:c.z.array(ir),isRead:c.z.boolean(),isStarred:c.z.boolean(),labels:c.z.array(sr),commentItems:c.z.array(Tt),attachments:c.z.array(or).default([])}),lr=c.z.object({type:c.z.literal("connected")}),ze=c.z.object({type:c.z.literal("status-update"),reportHubId:c.z.number(),statusType:c.z.enum(["star","read"]),value:c.z.boolean(),clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional()}),nt=c.z.string().optional(),at=c.z.object({type:c.z.literal("comment-add"),reportHubId:c.z.number(),comment:Tt,clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional(),sourceType:nt}),it=c.z.object({type:c.z.literal("comment-delete"),reportHubId:c.z.number(),commentId:c.z.number(),clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional(),sourceType:nt}),st=c.z.object({type:c.z.literal("report-create"),reportHubId:c.z.number(),report:rt,clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional()}),ot=c.z.object({type:c.z.literal("report-update"),reportHubId:c.z.number(),report:rt,clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional()}),lt=c.z.object({type:c.z.literal("report-publish"),reportHubId:c.z.number(),report:rt,clientTempId:c.z.string(),recipientRawUserId:c.z.number().optional()}),ut=c.z.object({type:c.z.literal("report-delete"),reportHubId:c.z.number(),clientTempId:c.z.string(),sourceType:nt}),Ct=c.z.discriminatedUnion("type",[lr,ze,at,it,st,ot,lt,ut]);var _t=require("crypto"),Ve=t=>{let e=JSON.stringify(t);return`"${(0,_t.createHash)("sha256").update(e).digest("hex")}"`};var ur=ue(1,"[Response]"),de=(t,e,r,a=200,p=ur)=>{let m=Ve(r),S=t.headers.get("If-None-Match");p.info(`[jsonResponseWithETag] ETag: ${m}, If-None-Match: ${S}`);let h=new Headers({"Content-Type":"application/json","Cache-Control":"private, max-age=0, must-revalidate","X-Content-Type-Options":"nosniff","X-Frame-Options":"DENY","Content-Security-Policy":"default-src 'none'",ETag:m});return e&&h.append("Set-Cookie",e),t.method==="GET"&&a===200&&S===m?new Response(null,{status:304,headers:h}):new Response(JSON.stringify(r),{status:a,headers:h})};var vt=require("events");var Ce=(t,e)=>{let[r,a]=t.split("-").map(Number),[p,m]=e.split("-").map(Number);return r!==p?r<p:a<=m},Be=class{constructor(e){this.config=e;this._emitter=new vt.EventEmitter;this._state="idle";this._refCount=0;this._lastId="$";this._emitter.setMaxListeners(0),this._logger=e.logger??ue(1,"[SSE Reader]")}subscribe(e,r){return this._emitter.on("entry",e),r&&this._emitter.on("error",r),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),r&&this._emitter.removeListener("error",r),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="$"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"&&this._refCount!==0){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitError(e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitError(new Error("Failed to create Redis client for SSE reader"));return}if(this._client.on("error",e=>{this._logger.error("Redis client error:",e)}),this._lastId==="$")try{let e=await this.config.redis?.getClient();if(e){let r=await e.xRevRange(this.config.streamKey,"+","-",{COUNT:1});this._lastId=r.length>0?r[0].id:"0-0"}}catch(e){this._logger.warn("Failed to resolve stream tail anchor; falling back to $:",e)}try{for(;this._state==="running"&&this._client?.isOpen;){let e=await this._client.xRead([{key:this.config.streamKey,id:this._lastId}],{BLOCK:5e3,COUNT:100});if(e)for(let r of e)for(let a of r.messages){this._lastId=a.id;try{let p=a.message?.data?JSON.parse(a.message.data):null,m=p?.type;if((m==="report-create"||m==="report-delete"||m==="report-publish")&&this.config.cache.invalidatePrefix("daily-report:ids"),m==="comment-add"||m==="comment-delete"||m==="status-update"){let S=p?.reportHubId;typeof S=="number"&&(this.config.cache.invalidate(`daily-report:detail:${S}`),this.config.cache.invalidatePrefix(`daily-report:detail:${S}:user:`))}}catch{}this._emitter.emit("entry",{id:a.id,message:a.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitError(e instanceof Error?e:new Error(String(e))))}finally{if(this._client?.isOpen)try{await this._client.quit()}catch{}this._client=void 0,this._state="idle",this._refCount>0&&this._startLoop()}}}async _stopLoop(){if(this._state==="running"){if(this._state="stopping",this._client?.isOpen)try{await this._client.quit()}catch{}for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50))}}_emitError(e){this._emitter.listenerCount("error")>0?this._emitter.emit("error",e):this._logger.error("SSE reader error (no error listeners):",e)}};var He=require("drizzle-orm");var dr="",cr=64,pr=t=>t.toLowerCase(),mr=t=>t.trim().toLowerCase();function dt(t){if(t==null)return null;if(!Array.isArray(t))return new Set;let e=new Set;for(let r of t){if(typeof r!="string")continue;let a=mr(r);a.length>0&&e.add(a)}return e}function he(t,e){return t===null?!0:e==null?!1:t.has(pr(e))}function Re(t){return t!==null&&t.size===0}function pt(t,e){if(e!==null)return e.size===0?He.sql`1 = 0`:(0,He.inArray)(He.sql`LOWER(${t})`,[...e])}var _e,ve,Ue=class Ue{constructor(e,r){Ze(this,_e);Ze(this,ve);et(this,_e,e),et(this,ve,r)}get visible(){return $e(this,_e)===null?null:new Set($e(this,_e))}get commentable(){return $e(this,ve)===null?null:new Set($e(this,ve))}static restrictTo(e){let r=typeof e=="object"&&e!==null&&"read"in e,a=dt(r?e.read:e),p=r?e.comment:void 0;if(p===void 0)return new Ue(a,a);let m=dt(p),S=new Set;for(let h of m??[])a.has(h)&&S.add(h);return new Ue(a,S)}static unrestricted(e){return new Ue(null,null)}};_e=new WeakMap,ve=new WeakMap;var ce=Ue;function Me(t){let e=ct(t.visible),r=ct(t.commentable);return e===r?e:`d:${e.length}:${e}${r}`}function ct(t){if(t===null)return"all";if(t.size===0)return"none";let e=[...t].sort().map(a=>`${a.length}:${a}`).join(dr);if(e.length<=cr)return`s:${e}`;let r=2166136261;for(let a=0;a<e.length;a++)r^=e.charCodeAt(a),r=Math.imul(r,16777619);return`sh:${(r>>>0).toString(16)}`}var P=(t,e)=>new Response(JSON.stringify(t),{status:e?.status??200,headers:{"Content-Type":"application/json"}}),je=200,kt=4e3,yr="stream interrupted by server error",hr=/^\d{4}-\d{2}-\d{2}$/,fr=15e3,Mt=Symbol("ids-stream-heartbeat"),br=12,gr=t=>{let e=t.searchParams.get("cursor_report_hub_id"),r=t.searchParams.get("cursor_business_date");if(e===null)return r===null?{cursor:null}:{invalid:!0};let a=Number.parseInt(e,10);return!Number.isSafeInteger(a)||String(a)!==e||a<=0?{invalid:!0}:r===null?{cursor:{businessDate:null,reportHubId:a}}:hr.test(r)?{cursor:{businessDate:r,reportHubId:a}}:{invalid:!0}};async function*Et(t,e,r=je){let a=e?At(t,e):0,p=!0;for(;;){let m=t.slice(a,a+(p?r:kt));a+=m.length;let S=a>=t.length,h=m[m.length-1];if(yield{items:m,nextCursor:S||!h?null:{businessDate:h.businessDate,reportHubId:h.reportHubId},isLast:S,...p?{total:t.length}:{}},p=!1,S)return}}var xt=(t,e,r,a)=>{let p=new TextEncoder,m=!1,S=null,h=new ReadableStream({async pull(u){if(m||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}let B=null;try{S===null&&(S=e.next());let y=new Promise(pe=>{B=setTimeout(()=>pe(Mt),fr)}),V=await Promise.race([S,y]);if(B!==null&&(clearTimeout(B),B=null),V===Mt){if(m||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(p.encode(`
|
|
2
|
+
`));return}S=null;let{value:F,done:U}=V;if(U){u.close();return}if(m||r.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(p.encode(`${JSON.stringify(F)}
|
|
3
|
+
`))}catch(y){if(B!==null&&clearTimeout(B),S=null,m||r.signal.aborted)return;a.error(`ids-stream emission failed: ${y instanceof Error?y.message:String(y)}`);try{u.enqueue(p.encode(`${JSON.stringify({error:yr})}
|
|
4
|
+
`)),u.close()}catch{}}},cancel(){m=!0,e.return(void 0).catch(()=>{})}}),L=new Headers({"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"private, no-cache, no-transform","X-Content-Type-Options":"nosniff"});return t&&L.append("Set-Cookie",t),new Response(h,{status:200,headers:L})},Rr=32*1024*1024,Dr=60,wr=4,Sr=12e4,Ir=1024,Ar=60,Tr=5,Cr=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),_r=/^[\x20-\x7E]+$/,vr=/^[\w.+-]+\/[\w.+-]+/,mt=t=>t&&_r.test(t)&&vr.test(t)?t:null,Nt=t=>encodeURIComponent(t).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),Lt=t=>t.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),Mr=t=>{switch(t){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},Er={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},xr=t=>{let e=new Map;return(r,a)=>{let p=e.get(r);p&&e.delete(r);let m=p??{tokens:t,lastRefillMs:a},S=Math.max(0,a-m.lastRefillMs);S>0&&(m.tokens=Math.min(t,m.tokens+S*t/6e4),m.lastRefillMs=a);let h=m.tokens>=1;for(h&&(m.tokens-=1),e.set(r,m);e.size>Ir;){let L=e.keys().next();if(L.done)break;e.delete(L.value)}return h}},kr=t=>{let e=0;return{tryAcquire:()=>e>=t?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},Nr=(t,e,r)=>{let a=setTimeout(e,r);a.unref?.();let p=()=>{clearTimeout(a),e()},m=!1;return new ReadableStream({pull(S){if(m){S.close(),p();return}m=!0,S.enqueue(t)},cancel(){p()}})},Lr=(t,e,r,a)=>{if(r===null&&a===null)return!0;let p=typeof e.sourceType=="string"?e.sourceType:void 0;switch(t.type){case"connected":case"status-update":return!0;case"report-create":case"report-update":case"report-publish":return he(r,t.report.sourceType);case"comment-add":case"comment-delete":return he(a,p??"Internal");case"report-delete":return he(r,p)}},$r=(t,e,r)=>{if(r===null||t.type!=="report-create"&&t.type!=="report-update"&&t.type!=="report-publish"||he(r,t.report.sourceType))return!1;let a=e.report;if(typeof a!="object"||a===null)return!1;let p=a;return p.comments=[],p.commentItems=[],!0};function yt(t){let{authenticate:e,service:r,encodeUserId:a,redis:p,sseReader:m,streamKey:S}=t,h=t.loginRedirectPath??"/auth/login",L=t.logger??ue(3,"[DailyReportAPI]"),u=t.logger??ue(3,"[DailyReportVisibility]"),B=t.logger??ue(1,"[DailyReportSSE]"),y=t.logger??ue(1,"[DailyReportAttachment]"),V=t.attachmentMaxBytes??Rr,F=xr(t.attachmentRateLimitPerMinute??Dr),U=kr(t.attachmentConcurrency??wr),pe=async(I,H="initial")=>{let C=t.resolveVisibleSourceTypes;if(!C)return ce.unrestricted("no visibility port injected: this deployment does not restrict by source type");try{let T=await C(I,{reason:H});return T==null?ce.unrestricted("visibility port returned null/undefined: this deployment opts out of source-type filtering"):ce.restrictTo(T)}catch(T){return u.error("resolveVisibleSourceTypes threw; failing closed (deny all)",T),ce.restrictTo([])}},Ee=async({request:I})=>{let{user:H,cookie:C}=await e(I,{failureRedirect:h}),T=new Headers;C&&T.append("Set-Cookie",C);let _=null;H&&(_=await r.getUserIdByExternalId(H.id));let $=_?a(_):null;return{data:{user:H,userId:$},headers:T}},xe={"business-date":async(I,H,C,T,_)=>{let $=le(I.searchParams.get("businessDate")),D=I.searchParams.get("forceRefresh")==="true";if(!$)return de(C,H,{error:{message:"Invalid business date"}},400);let k=await r.getDailyReportsByBusinessDateByExternalId(_,$,T.id,{forceRefresh:D});return de(C,H,{businessDate:$,reports:k},200)},"ids-stream":async(I,H,C,T,_)=>{let $=gr(I);if("invalid"in $)return de(C,H,{error:{message:"Invalid cursor"}},400);let D=I.searchParams.get("forceRefresh")==="true",k=r.getDailyReportIdsByExternalId(_,T.id,{forceRefresh:D});if(k.catch(()=>{}),$.cursor)return xt(H,Et(await k,$.cursor),C,L);let K=r.getDailyReportIdsFirstPageByExternalId(_,T.id,je);K.catch(()=>{});let v=(async function*(){let M=await Promise.race([k.then(Y=>({kind:"full",items:Y}),Y=>({kind:"full-error",error:Y})),K.then(Y=>({kind:"page",items:Y}),()=>({kind:"page-error"}))]),Z=null,w=null;if(M.kind==="full")w=M.items;else if(M.kind==="page"||M.kind==="full-error"){let Y=M.kind==="page"?M.items:await K;if(Y.length<je){yield{items:Y,nextCursor:null,isLast:!0,total:Y.length};return}let R=Y[Y.length-1];Z={businessDate:R.businessDate,reportHubId:R.reportHubId},yield{items:Y,nextCursor:Z,isLast:!1}}w===null&&(w=await k),yield*Et(w,Z,Z?kt:je)})();return xt(H,v,C,L)},report:async(I,H,C,T,_)=>{let $=I.searchParams.get("reportHubId"),D=I.searchParams.get("forceRefresh")==="true",k=$?Number.parseInt($,10):NaN;if(!Number.isFinite(k)||k<=0)return de(C,H,{error:{message:"Invalid reportHubId"}},400);let K=await r.getDailyReportDetailByIdByExternalId(_,k,T.id,{snapshot:!0,forceRefresh:D});return K?de(C,H,{report:K},200):de(C,H,{error:{message:"Report not found"}},404)}};return{index:{loader:Ee},api:{loader:async({request:I,params:H})=>{let{user:C,cookie:T}=await e(I,{failureRedirect:null}),_=T??null;if(!C)return de(I,_,{error:{message:"Unauthorized"}},401);if(I.method!=="GET")return de(I,_,{error:{message:"Method not allowed"}},405);let $=H.endpoint??"",D=xe[$];if(!D)return de(I,_,{error:{message:"Unknown endpoint"}},404);let k=Date.now();try{let K=new URL(I.url),v=await pe(I);return await D(K,_,I,C,v)}catch(K){let v=Date.now()-k,M=K instanceof Error?K:new Error(String(K));return L.error(`500 endpoint=${$} elapsed=${v}ms name=${M.name} code=${"code"in M?M.code:"N/A"} message=${M.message}`),L.error("Stack:",M.stack),de(I,_,{error:{message:"Internal Server Error"}},500)}},action:async({request:I,params:H})=>{let{user:C}=await e(I,{failureRedirect:null});if(!C)return P({error:"Unauthorized"},{status:401});if(H.endpoint!=="action")return P({error:"Unknown endpoint"},{status:404});let _=await r.getUserIdByExternalId(C.id);if(!_)return P({error:"User not found"},{status:404});let $=await pe(I),D=await I.formData(),k=D.get("intent"),K=D.get("reportHubId"),v=K?Number(K):NaN,M=D.get("businessDate"),Z=Number(D.get("operationTimestamp")),w=D.get("clientTempId");if(k==="clearCache")return t.enableDevCacheClear?(await r.clearCache(),P({status:"OK",intent:"clearCache"})):P({error:"Invalid intent"},{status:400});if(!w)return P({error:"clientTempId required"},{status:400});if(k!=="create"&&(!v||Number.isNaN(v)))return P({error:"Invalid reportHubId"},{status:400});let Y=async(R,O,j)=>{let ee=D.get(O);if(ee===null)return P({error:`${O} required`},{status:400});try{let re=await j(ee==="true");return P({status:"OK",intent:R,updatedStatus:{isStarred:re.isStarred,isRead:re.isRead},operationTimestamp:Z,reportHubId:String(v),clientTempId:w})}catch(re){if(re instanceof Error&&re.message==="Not Found")return P({error:"Report not found"},{status:404});throw re}};switch(k){case"create":{if(!M)return P({error:"businessDate required"},{status:400});let R=await r.createDailyReport(_,M,w);return P({status:"OK",intent:"create",report:R,reportHubId:String(R.reportHubId),clientTempId:w})}case"update":{let R=D.get("title"),O=D.get("content");try{return await r.updateDailyReport(v,_,{title:R,content:O},w),P({status:"OK",intent:"update",reportHubId:String(v),clientTempId:w})}catch(j){if(j instanceof Error){if(j.message==="Unauthorized")return P({error:"Unauthorized"},{status:403});if(j.message==="Not Found")return P({error:"Report not found"},{status:404})}throw j}}case"publish":try{let R=await r.publishDailyReport(v,_,w);return P({status:"OK",intent:"publish",reportHubId:String(v),clientTempId:w,report:R})}catch(R){if(R instanceof Error){if(R.message==="Unauthorized")return P({error:"Unauthorized"},{status:403});if(R.message==="Not Found")return P({error:"Report not found"},{status:404})}throw R}case"delete":try{return await r.deleteDailyReport(v,_,w),P({status:"OK",intent:"delete",reportHubId:String(v),clientTempId:w})}catch(R){if(R instanceof Error){if(R.message==="Unauthorized")return P({error:"Unauthorized"},{status:403});if(R.message==="Not Found")return P({error:"Report not found"},{status:404})}throw R}case"toggleStar":return await Y("toggleStar","isStarred",R=>r.setStarStatus($,_,v,M,R,w));case"toggleRead":return await Y("toggleRead","isRead",R=>r.setReadStatus($,_,v,M,R,w));case"addComment":{let R=D.get("content");if(!R)return P({error:"Content required"},{status:400});try{let O=await r.addComment($,_,v,R,M,w),j={...O,userId:O.userId};return P({status:"OK",intent:"addComment",newComment:j,reportHubId:String(v),clientTempId:w})}catch(O){if(O instanceof Error){if(O.message==="Not Found")return P({error:"Report not found"},{status:404});if(O.message.startsWith("Comments are restricted"))return P({error:"Comments are restricted for this report"},{status:403})}throw O}}case"deleteComment":{let R=Number(D.get("commentId"));if(!R||Number.isNaN(R))return P({error:"Invalid commentId"},{status:400});try{return await r.deleteComment($,_,v,R,M,w),P({status:"OK",reportHubId:String(v),deletedCommentId:String(R),clientTempId:w})}catch(O){if(O instanceof Error){if(O.message==="Unauthorized")return P({error:"Unauthorized"},{status:403});if(O.message==="Not Found")return P({error:"Comment not found"},{status:404})}throw O}}default:return P({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:I,params:H})=>{let{user:C}=await e(I,{failureRedirect:null});if(!C)return new Response("Unauthorized",{status:401});let T=await r.getUserIdByExternalId(C.id);if(!T)return new Response("Forbidden",{status:403});if(H.endpoint!=="updates")return new Response("Not Found",{status:404});let _=await pe(I),$=_.visible,D=_.commentable,k=0,K=0,M=new URL(I.url).searchParams.get("lastEventId")||I.headers.get("Last-Event-ID"),Z=new TextEncoder,w=null,Y=null,R=null,O=!1,j=()=>{if(!O){if(O=!0,Y&&(clearInterval(Y),Y=null),R&&(R(),R=null),w)try{w.desiredSize!==null&&w.close()}catch{}finally{w=null}O=!1}},ee=me=>{w&&w.desiredSize!==null&&w.enqueue(Z.encode(`id: ${me}
|
|
5
5
|
data: ${JSON.stringify({type:"connected"})}
|
|
6
6
|
|
|
7
|
-
`))},
|
|
8
|
-
data: ${
|
|
7
|
+
`))},re=(me,te)=>{if(te.data)try{let Q=JSON.parse(te.data),x=Ct.safeParse(Q);if(!x.success){B.error("SSE message validation failed:",x.error.format());return}let z=x.data,X=typeof Q.recipientRawUserId=="number"?Q.recipientRawUserId:void 0;if(z.type==="status-update"){if(X===void 0||X!==T)return}else if(X!==void 0&&X!==T)return;if(!Lr(z,Q,$,D)){ee(me);return}let Ie=$r(z,Q,D),ye;if("recipientRawUserId"in Q){let{recipientRawUserId:Ne,...fe}=Q;ye=JSON.stringify(fe)}else Ie?ye=JSON.stringify(Q):ye=te.data;w&&w.desiredSize!==null&&w.enqueue(Z.encode(`id: ${me}
|
|
8
|
+
data: ${ye}
|
|
9
9
|
|
|
10
|
-
`))}catch(
|
|
10
|
+
`))}catch(Q){B.error(`[SSE:${T}] processEntry error:`,Q)}},Se=new ReadableStream({async start(me){w=me,Y=setInterval(()=>{try{if(w&&w.desiredSize!==null){if(w.enqueue(Z.encode(`: keep-alive
|
|
11
11
|
|
|
12
|
-
`)),++
|
|
12
|
+
`)),++k%br===0){let x=++K;pe(I,"refresh").then(z=>{x===K&&($=z.visible,D=z.commentable)})}}else j()}catch{j()}},5e3),I.signal.addEventListener("abort",()=>{j()});let te=M||"0-0",Q=null;if(R=m.subscribe(x=>{Ce(x.id,te)||(Q===null&&(Q=x.id),te=x.id,re(x.id,x.message))},x=>{B.error(`[SSE:${T}] Fan-Out reader error:`,x),j()}),!M)try{let x=await p?.getClient();if(x){let z=await x.xRevRange(S,"+","-",{COUNT:1});z.length>0&&!Ce(z[0].id,te)&&(te=z[0].id)}}catch{}if(w&&w.desiredSize!==null){let x=`data: ${JSON.stringify({type:"connected"})}
|
|
13
13
|
|
|
14
|
-
`,
|
|
15
|
-
${k}`:k;D.enqueue(_.encode(Z))}if(Y)try{let k=await m?.getClient();if(k){let Z=await k.xRange(A,Y,"+",{COUNT:1e3});for(let ie of Z)ie.id!==Y&&(Ne(ie.id,ee)||(ee=ie.id,X(ie.id,ie.message)))}}catch(k){P.error(`[SSE:${T}] catch-up xRange error:`,k)}},cancel(){R()}});return new Response(W,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}},attachment:{loader:async({request:I,params:H})=>{let v=null,T=(M,U,w)=>{let N=new Headers({"Content-Type":"application/json"});return w!==void 0&&N.set("Retry-After",String(w)),v&&N.append("Set-Cookie",v),new Response(JSON.stringify({error:{message:U}}),{status:M,headers:N})};try{let{user:M,cookie:U}=await e(I,{failureRedirect:null});if(v=U??null,!M)return T(401,"Unauthorized");if(I.method!=="GET"&&I.method!=="HEAD")return T(405,"Method not allowed");let w=t.attachmentIdCodec,N=t.readAttachment;if(!(w&&N))return T(404,"Attachment not found");let Y=H.token??"",_=w.decode(Y);if(_===null||!Number.isSafeInteger(_)||_<=0)return T(400,"Invalid attachment token");let D=await r.getUserIdByExternalId(M.id);if(!D)return T(403,"Forbidden");if(!z(D,Date.now()))return p.error(`429 attachment=${_} viewer=${D} reason=rate_limit`),T(429,"Too many requests",wr);let Q=await pe(I),E=await r.getAttachmentForUser(Q,_,D);if(!E)return p.error(`404 attachment=${_} viewer=${D} reason=not_visible`),T(404,"Attachment not found");if(E.fileSize!=null&&E.fileSize>K)return p.error(`413 attachment=${_} viewer=${D} reason=db_size`),T(413,"Attachment too large");if(!B.tryAcquire())return p.error(`503 attachment=${_} viewer=${D} reason=concurrency`),T(503,"Too many concurrent downloads",Sr);let F=!1,R=()=>{F||(F=!0,B.release())},O=!1;try{let X=I.method==="HEAD",W=await N(E.filePath,{maxBytes:K,head:X,principal:s(D)});if(!W.ok){let me=Cr(W.reason);return W.reason==="not_found"&&r.markAttachmentMissing(_).catch(we=>{p.error(`markAttachmentMissing failed attachment=${_} message=${we instanceof Error?we.message:"unknown"}`)}),p.error(`${me} attachment=${_} viewer=${D} reason=${W.reason} code=${W.code??"-"}`),T(me,_r[me]??"Attachment storage unavailable")}let j=st(E.fileType)??st(W.contentType)??"application/octet-stream",ee=Ir.has(j),k=new URL(I.url).searchParams.get("download")==="1",Z=ee?j:"application/octet-stream",ie=ee&&!k?"inline":"attachment",ue=W.size??W.bytes.byteLength,oe=new Headers({"Content-Type":Z,"Content-Length":String(ue),"Content-Disposition":`${ie}; filename="${xt(E.fileName)}"; filename*=UTF-8''${Et(E.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return v&&oe.append("Set-Cookie",v),r.markAttachmentPresent(_).catch(me=>{p.error(`markAttachmentPresent failed attachment=${_} message=${me instanceof Error?me.message:"unknown"}`)}),p.info(`200 attachment=${_} viewer=${D} type=${Z} disposition=${ie} bytes=${ue}`),X?new Response(null,{status:200,headers:oe}):(O=!0,new Response(Er(W.bytes,R,Rr),{status:200,headers:oe}))}finally{O||R()}}catch(M){if(M instanceof Response)throw M;return p.error(`500 attachment=? viewer=? reason=unexpected message=${M instanceof Error?M.message:"unknown"}`),T(500,"Attachment request failed")}}}}}var a=require("drizzle-orm");var Re=t=>(0,a.getColumns)(t),te=(t,e)=>{if(!t)return null;let r=t instanceof Date?t:new Date(t);if(Number.isNaN(r.getTime()))return typeof t=="string"?t:null;let s=r.getFullYear(),m=s<0?`-${String(-s).padStart(4,"0")}`:String(s).padStart(4,"0"),c=String(r.getMonth()+1).padStart(2,"0"),A=String(r.getDate()).padStart(2,"0");if(e==="YYYY-MM-DD")return`${m}-${c}-${A}`;let y=String(r.getHours()).padStart(2,"0"),L=String(r.getMinutes()).padStart(2,"0"),u=String(r.getSeconds()).padStart(2,"0");return`${m}-${c}-${A} ${y}:${L}:${u}`};function ot(t){let{db:e,tables:r,userTable:s,resolveUserId:m,encodeUserId:c,redis:A,cache:y,epochs:L}=t,{hub:u,internal:P,comment:p,label:K,hubLabel:z,userStatus:B}=r,pe=t.externalSources??[],_e=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],ve=_e[0]??"\u4E0B\u66F8\u304D",re=t.logger??le(1,"[DailyReportService]"),Me="daily-report:ids",lt=t.idsTtlMs??18e4,De="daily-report:ids:epoch",I="daily-report:business-date:",H=t.businessDateTtlMs??3e5,v="daily-report:date-epoch:",T="daily-report:detail-epoch:",M=t.streamKey??"daily-report:sse-stream",U=t.streamMaxLen??1e4,w=n=>L.incrementEpoch(n),N=n=>at(u.sourceType,n),Y=(n,o)=>`${Me}:user:${n}:st:${o}`,_=n=>`${Me}:user:${n}:`,D=(n,o,i)=>`daily-report:date:${n}:user:${o}:st:${i}`,Q=(n,o)=>`daily-report:date:${n}:user:${o}:`,E=(n,o,i)=>`daily-report:detail:${n}:user:${o}:st:${i}`,F=(n,o)=>`daily-report:detail:${n}:user:${o}:`,R=async(n,o)=>{let i=await A?.getClient();if(!i){re.warn(`[SSE] Redis client unavailable (${o})`);return}let h=Date.now();try{await i.xAdd(M,"*",{data:JSON.stringify(n)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:U}});let f=Date.now()-h;f>1e3&&re.warn(`[SSE] Slow publish (${o}): ${f}ms`)}catch(f){re.error(`[SSE] Redis publish failed (${o}):`,f)}},O=n=>n==null||n===""?null:/^\d+$/.test(n)?c(Number(n)):n,X=()=>{let n={};for(let o of pe)n[`ext_${o.sourceType}`]=Re(o.table);return n},W=n=>{let o=n;for(let i of pe)o=o.leftJoin(i.table,(0,a.and)((0,a.eq)(u.sourceType,i.sourceType),(0,a.eq)(u.sourceIdNum,i.idColumn)));return o},j=(n,o)=>{let{hub:i,internal:h}=n,f=i.summary,b=[],g=null,S=null,x=null,J=null,q=null,G=null,ne=[],he=pe.find(C=>C.sourceType===i.sourceType),Ae=he?n[`ext_${he.sourceType}`]:void 0;if(he&&Ae){let C=he.mapRow(Ae);C.content!==void 0&&(f=C.content),C.employeeName!==void 0&&(G=C.employeeName),C.category!==void 0&&(g=C.category),C.creationCategory!==void 0&&(S=C.creationCategory),C.visitTimeFrom!==void 0&&(x=C.visitTimeFrom),C.visitTimeTo!==void 0&&(J=C.visitTimeTo),C.customerName!==void 0&&(q=C.customerName),C.interviewers!==void 0&&(b=C.interviewers),C.comments!==void 0&&(ne=C.comments)}else i.sourceType==="Internal"&&h&&(f=h.body);let be=(n.labels??[]).map(C=>({id:C.id,name:C.name,color:C.color})),ge=n.comments??[],ae=S?_e.includes(S):!1,V=Se?.[0]??null;return ae&&V&&!be.some(C=>C.id===V)&&be.push({id:V,name:ve,color:null}),{reportHubId:i.id,date:te(i.businessDate,"YYYY-MM-DD"),author:n.creatorName??O(i.createdBy)??"",userId:i.userId?c(i.userId):"",sourceType:i.sourceType??"Internal",createdAt:te(i.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:te(i.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:O(i.updatedBy),employeeName:G??n.creatorName??O(i.createdBy),category:g,creationCategory:S,visitTimeFrom:x,visitTimeTo:J,customerName:q,interviewers:b,subject:i.title,content:f,comments:ne,isRead:n.isRead??!1,isStarred:n.isStarred??!1,labels:be,commentItems:ge.map(C=>({...C,userId:c(C.userId),isMine:o?C.userId===o:!1})),attachments:n.attachments}},ee=async(n,o)=>{let i=(0,a.aliasedTable)(z,"draft_label"),h=await Ie();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(i,(0,a.and)((0,a.eq)(i.hubId,u.id),(0,a.inArray)(i.labelId,h))).where((0,a.and)((0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,o),(0,a.isNull)(u.userId),(0,a.isNull)(i.hubId)),N(n.visible))).orderBy((0,a.desc)(u.businessDate),(0,a.desc)(u.id))).map(b=>({...b,businessDate:te(b.businessDate,"YYYY-MM-DD")}))},k=async(n,o,i)=>{let h=await oe(o);if(!h)return[];if(fe(n.visible))return[];let f=(0,a.aliasedTable)(z,"draft_label"),b=await Ie();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).top(i).from(u).leftJoin(f,(0,a.and)((0,a.eq)(f.hubId,u.id),(0,a.inArray)(f.labelId,b))).where((0,a.and)((0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,h),(0,a.isNull)(u.userId),(0,a.isNull)(f.hubId)),N(n.visible))).orderBy((0,a.desc)(u.businessDate),(0,a.desc)(u.id))).map(S=>({...S,businessDate:te(S.businessDate,"YYYY-MM-DD")}))},Z=async(n,o)=>{let i=await W(e.select({hub:Re(u),internal:Re(P),creatorName:s.displayName,...X()}).from(u)).leftJoin(P,(0,a.eq)(u.id,P.hubId)).leftJoin(s,(0,a.eq)(u.userId,s.id)).where((0,a.and)((0,a.eq)(u.businessDate,a.sql`${o}`),(0,a.isNull)(u.deletedAt),N(n.visible))).orderBy((0,a.desc)(u.id)),h=await Ue(i.map(f=>f.hub.id));return i.map(f=>j({...f,attachments:h.get(f.hub.id)??[]}))},ie=n=>`${I}${n}`,ue=new Map,oe=async n=>{if(!t.disableUserIdCache&&ue.has(n))return ue.get(n)??null;let o=await m(n);return o!==null&&!t.disableUserIdCache&&ue.set(n,o),o},me=async(n,o,{forceRefresh:i=!1,snapshot:h=!1,ttlMsOverride:f}={})=>{let b=await oe(o);if(!b)return[];if(fe(n.visible))return[];let g=Y(b,Ce(n));return y.getOrFetch({cacheKey:g,fetcher:async()=>await ee(n,b),forceRefresh:i,snapshot:h,ttlMsOverride:f??lt,epochKey:De,refreshAheadRatio:.5})},we=(n,o,{forceRefresh:i=!1,snapshot:h=!1,ttlMsOverride:f}={})=>{let b=se(o);return b?fe(n.visible)?Promise.resolve([]):y.getOrFetch({cacheKey:`${ie(b)}:st:${Ce(n)}`,fetcher:()=>Z(n,b),forceRefresh:i,snapshot:h,ttlMsOverride:f??H}):Promise.resolve([])},Se=null,Be=async()=>(Se!==null||(Se=(await e.select({id:K.id}).from(K).where((0,a.inArray)(K.name,_e)).orderBy(K.id)).map(o=>o.id)),Se),Ie=async()=>{let n=await Be();return n.length>0?n:[-1]},Ke=async()=>{let n=await Be();if(n.length===0)return null;let[o]=await e.select({id:K.id}).top(1).from(K).where((0,a.eq)(K.name,ve));return o?.id??n[0]},Nt=(n,o)=>o!=null?"absent":n!=null?"present":"unknown",Ue=async n=>{let o=new Map,i=r.attachment,h=t.attachmentIdCodec;if(n.length===0||!i||!h)return o;let f=await e.select({id:i.id,hubId:i.hubId,fileName:i.fileName,fileType:i.fileType,fileSize:i.fileSize,createdAt:i.createdAt,objectCheckedAt:i.objectCheckedAt,objectMissingAt:i.objectMissingAt}).from(i).where((0,a.inArray)(i.hubId,n)).orderBy((0,a.asc)(i.createdAt),(0,a.asc)(i.id));for(let b of f){let g={id:h.encode(Number(b.id)),fileName:String(b.fileName),fileType:b.fileType?String(b.fileType):null,fileSize:b.fileSize!=null?Number(b.fileSize):null,createdAt:te(b.createdAt,"YYYY-MM-DD HH:mm:ss"),state:Nt(b.objectCheckedAt,b.objectMissingAt)},S=o.get(Number(b.hubId));S?S.push(g):o.set(Number(b.hubId),[g])}return o},Lt=async(n,o,i)=>{let h=r.attachment;if(!h||fe(n.visible))return null;let f=await Ie(),b=(0,a.aliasedTable)(z,"draft_label");return(await e.select({fileName:h.fileName,filePath:h.filePath,fileType:h.fileType,fileSize:h.fileSize}).top(1).from(h).innerJoin(u,(0,a.eq)(u.id,h.hubId)).leftJoin(b,(0,a.and)((0,a.eq)(b.hubId,u.id),(0,a.inArray)(b.labelId,f))).where((0,a.and)((0,a.eq)(h.id,o),(0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,i),(0,a.isNull)(b.hubId)),N(n.visible))))[0]??null},$t=async n=>{let o=r.attachment;if(!o)return;let i=new Date;try{await e.update(o).set({objectCheckedAt:i,objectMissingAt:i,updatedAt:i}).where((0,a.eq)(o.id,n))}catch(h){re.error("markAttachmentMissing failed",h)}},Pt=async n=>{let o=r.attachment;if(!o)return;let i=new Date;try{await e.update(o).set({objectCheckedAt:i,objectMissingAt:null,updatedAt:i}).where((0,a.eq)(o.id,n))}catch(h){re.error("markAttachmentPresent failed",h)}},Bt=async(n,o,i,{forceRefresh:h=!1,snapshot:f=!1,ttlMsOverride:b}={})=>{let g=await oe(i);if(!g)return[];let S=se(o);if(!S)return[];if(fe(n.visible))return[];let x=D(S,g,Ce(n));return y.getOrFetch({cacheKey:x,fetcher:async()=>{let J=await Ie(),q=(0,a.aliasedTable)(z,"draft_label"),G=await W(e.select({hub:Re(u),internal:Re(P),isRead:B.isRead,isStarred:B.isStarred,creatorName:s.displayName,...X()}).from(u)).leftJoin(P,(0,a.eq)(u.id,P.hubId)).leftJoin(B,(0,a.and)((0,a.eq)(u.id,B.hubId),(0,a.eq)(B.userId,g))).leftJoin(q,(0,a.and)((0,a.eq)(q.hubId,u.id),(0,a.inArray)(q.labelId,J))).leftJoin(s,(0,a.eq)(u.userId,s.id)).where((0,a.and)((0,a.eq)(u.businessDate,a.sql`${S}`),(0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,g),(0,a.isNull)(q.hubId)),N(n.visible))).orderBy((0,a.desc)(u.id));if(G.length===0)return[];let ne=G.map(V=>V.hub.id),he=await e.select({hubId:z.hubId,id:K.id,name:K.name,color:K.color}).from(z).innerJoin(K,(0,a.eq)(z.labelId,K.id)).where((0,a.inArray)(z.hubId,ne)),Ae=await e.select({hubId:p.hubId,id:p.id,body:p.body,createdAt:p.createdAt,userId:p.userId,userName:s.displayName}).from(p).leftJoin(s,(0,a.eq)(p.userId,s.id)).where((0,a.inArray)(p.hubId,ne)).orderBy((0,a.asc)(p.createdAt)),be=await Ue(ne),ge=new Map,ae=new Map;for(let V of he){let C=ge.get(V.hubId);C||(C=[],ge.set(V.hubId,C)),C.push({id:V.id,name:V.name,color:V.color})}for(let V of Ae){let C=ae.get(V.hubId);C||(C=[],ae.set(V.hubId,C)),C.push({id:V.id,content:V.body,createdAt:te(V.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:V.userId,userName:V.userName||""})}return G.map(V=>{let C=V.hub.id;return j({...V,attachments:be.get(C)??[],labels:ge.get(C)||[],comments:ae.get(C)||[]},g)})},forceRefresh:h,snapshot:f,ttlMsOverride:b??H,epochKey:`${v}${S}`})},Ee=async(n,o,i,{forceRefresh:h=!1,snapshot:f=!1,ttlMsOverride:b}={})=>{if(fe(n.visible))return null;let g=E(o,i,Ce(n));return(await y.getOrFetch({cacheKey:g,fetcher:async()=>{let x=await Ie(),J=(0,a.aliasedTable)(z,"draft_label"),q=await W(e.select({hub:Re(u),internal:Re(P),isRead:B.isRead,isStarred:B.isStarred,creatorName:s.displayName,...X()}).from(u)).leftJoin(P,(0,a.eq)(u.id,P.hubId)).leftJoin(B,(0,a.and)((0,a.eq)(u.id,B.hubId),(0,a.eq)(B.userId,i))).leftJoin(J,(0,a.and)((0,a.eq)(J.hubId,u.id),(0,a.inArray)(J.labelId,x))).leftJoin(s,(0,a.eq)(u.userId,s.id)).where((0,a.and)((0,a.eq)(u.id,o),(0,a.isNull)(u.deletedAt),(0,a.or)((0,a.eq)(u.userId,i),(0,a.isNull)(J.hubId)),N(n.visible)));if(q.length===0)return[];let G=q[0].hub.id,ne=await e.select({id:K.id,name:K.name,color:K.color}).from(z).innerJoin(K,(0,a.eq)(z.labelId,K.id)).where((0,a.eq)(z.hubId,G)),he=await e.select({id:p.id,body:p.body,createdAt:p.createdAt,userId:p.userId,userName:s.displayName}).from(p).leftJoin(s,(0,a.eq)(p.userId,s.id)).where((0,a.eq)(p.hubId,G)).orderBy((0,a.asc)(p.createdAt)),Ae=await Ue([G]),be=ne.map(ae=>({id:ae.id,name:ae.name,color:ae.color})),ge=he.map(ae=>({id:ae.id,content:ae.body,createdAt:te(ae.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:ae.userId,userName:ae.userName||""}));return[j({...q[0],attachments:Ae.get(G)??[],labels:be,comments:ge},i)]},forceRefresh:h,snapshot:f,ttlMsOverride:b??H,epochKey:`${T}${o}`}))[0]??null},Ut=async(n,o,i,h={})=>{let f=await oe(i);return f?Ee(n,o,f,h):null},Ht=async n=>{let[o]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt}).top(1).from(u).where((0,a.eq)(u.id,n));return o??null},ut=async(n,o)=>{let i=await Ht(o);if(!i||i.deletedAt||!ye(n.visible,i.sourceType))throw new Error("Not Found")},Ot=async(n,o,i,h,f,b)=>{await ut(n,i);let g=await e.select().top(1).from(B).where((0,a.and)((0,a.eq)(B.hubId,i),(0,a.eq)(B.userId,o))),S;if(g.length>0?g[0].isStarred!==f?S=(await e.update(B).set({isStarred:f,updatedAt:new Date,updatedBy:String(o)}).output().where((0,a.and)((0,a.eq)(B.hubId,i),(0,a.eq)(B.userId,o))))[0]:S=g[0]:S=(await e.insert(B).output().values({hubId:i,userId:o,isStarred:f,isRead:!1,createdAt:new Date,createdBy:String(o),updatedAt:new Date,updatedBy:String(o)}))[0],h){let x=se(h);x&&(y.invalidatePrefix(Q(x,o)),await w(`${v}${x}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(F(i,o)),await w(`${T}${i}`),await R(Oe.parse({type:"status-update",reportHubId:i,recipientRawUserId:o,statusType:"star",value:f,clientTempId:b}),"setStarStatus"),S},Yt=async(n,o,i,h,f,b)=>{await ut(n,i);let g=await e.select().top(1).from(B).where((0,a.and)((0,a.eq)(B.hubId,i),(0,a.eq)(B.userId,o))),S;if(g.length>0?g[0].isRead!==f?S=(await e.update(B).set({isRead:f,updatedAt:new Date,updatedBy:String(o)}).output().where((0,a.and)((0,a.eq)(B.hubId,i),(0,a.eq)(B.userId,o))))[0]:S=g[0]:S=(await e.insert(B).output().values({hubId:i,userId:o,isRead:f,isStarred:!1,createdAt:new Date,createdBy:String(o),updatedAt:new Date,updatedBy:String(o)}))[0],h){let x=se(h);x&&(y.invalidatePrefix(Q(x,o)),await w(`${v}${x}`))}return y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(F(i,o)),await w(`${T}${i}`),await R(Oe.parse({type:"status-update",reportHubId:i,recipientRawUserId:o,statusType:"read",value:f,clientTempId:b}),"setReadStatus"),S},dt=async(n,o)=>{if(o===null)return;let i=await Ie(),[h]=await e.select({hubId:z.hubId}).top(1).from(z).where((0,a.and)((0,a.eq)(z.hubId,n),(0,a.inArray)(z.labelId,i)));return h?o:void 0},Ft=async(n,o,i,h,f,b)=>{let[g]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt,userId:u.userId}).top(1).from(u).where((0,a.eq)(u.id,i));if(!g||g.deletedAt)throw new Error("Not Found");if(!ye(n.visible,g.sourceType))throw new Error("Not Found");if(g.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let S=await dt(i,g.userId),[x]=await e.insert(p).output().values({hubId:i,userId:o,body:h,createdAt:new Date,createdBy:String(o),updatedAt:new Date,updatedBy:String(o)}),[J]=await e.select({displayName:s.displayName}).top(1).from(s).where((0,a.eq)(s.id,o)),q=J?.displayName??"Unknown";if(f){let ne=se(f);ne&&(y.invalidatePrefix(`daily-report:date:${ne}:user:`),await w(`${v}${ne}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await w(`${T}${i}`);let G={id:x.id,userId:c(x.userId),userName:q,content:x.body,createdAt:te(x.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await R(We.parse({type:"comment-add",reportHubId:i,comment:G,clientTempId:b,recipientRawUserId:S,sourceType:g.sourceType}),"addComment"),G},qt=async(n,o)=>await n.select().top(1).from(p).where((0,a.eq)(p.id,o)),zt=async(n,o,i,h,f,b)=>{let g=await qt(e,h);if(g.length===0)throw new Error("Not Found");if(g[0].hubId!==i)throw new Error("Not Found");let[S]=await e.select({userId:u.userId,sourceType:u.sourceType}).top(1).from(u).where((0,a.eq)(u.id,g[0].hubId));if(!(S&&ye(n.visible,S.sourceType)))throw new Error("Not Found");if(g[0].userId!==o)throw new Error("Unauthorized");let x=await dt(i,S.userId);if(await e.delete(p).where((0,a.eq)(p.id,h)),f){let J=se(f);J&&(y.invalidatePrefix(`daily-report:date:${J}:user:`),await w(`${v}${J}`))}y.invalidate(`daily-report:detail:${i}`),y.invalidatePrefix(`daily-report:detail:${i}:user:`),await w(`${T}${i}`),await R(Ze.parse({type:"comment-delete",reportHubId:i,commentId:h,clientTempId:b,recipientRawUserId:x,sourceType:S?.sourceType}),"deleteComment")},Kt=async(n,o,i)=>{re.info("createDailyReport called",{userId:n,businessDate:o});let[h]=await e.select({displayName:s.displayName}).from(s).where((0,a.eq)(s.id,n)),f=h?.displayName??c(n);try{let b=await e.transaction(async x=>{re.info("Starting transaction");let J=`internal-temp-${Date.now()}-${Math.random()}`,[q]=await x.insert(u).output().values({sourceType:"Internal",sourceId:J,businessDate:new Date(o),userId:n,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)});await x.update(u).set({sourceId:String(q.id)}).where((0,a.eq)(u.id,q.id)),re.info("Hub created",q),await x.insert(P).values({hubId:q.id,body:"",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)}),re.info("Internal created"),re.info("Calling getDraftLabelId");let G=await Ke();re.info("draftLabelId",G);let ne=[];return G&&(await x.insert(z).values({hubId:q.id,labelId:G,createdAt:new Date,createdBy:String(n)}),ne.push({id:G,name:ve,color:null})),re.info("Label assigned"),{reportHubId:q.id,date:o,createdAt:te(q.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:c(n),sourceType:"Internal",employeeName:f,updatedBy:c(n),updatedAt:te(q.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:q.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:ne,commentItems:[],attachments:[]}}),g=se(o);g&&y.invalidatePrefix(Q(g,n)),y.invalidatePrefix(I),y.invalidatePrefix(_(n)),await w(De),g&&await w(`${v}${g}`);let S=await Ee(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),b.reportHubId,n,{forceRefresh:!0});if(S){let x=await Be(),J=S.labels.some(q=>x.includes(q.id));await R(et.parse({type:"report-create",reportHubId:S.reportHubId,report:S,clientTempId:i,recipientRawUserId:J?n:void 0}),"createDailyReport")}return S??b}catch(b){throw re.error("Error in createDailyReport",b),b}},He=async(n,o)=>await n.select().top(1).from(u).where((0,a.eq)(u.id,o)),Ve=async(n,o,i)=>{await n.update(u).set(i).where((0,a.eq)(u.id,o))},ct=async(n,o,i)=>{await n.update(P).set(i).where((0,a.eq)(P.hubId,o))},pt=async(n,o,i)=>{await n.delete(z).where((0,a.and)((0,a.eq)(z.hubId,o),(0,a.eq)(z.labelId,i)))};return{streamKey:M,streamMaxLen:U,clearCache:async()=>{y.clearAll(),ue.clear(),Se=null,L&&await w(De),re.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(n,o)=>{y.invalidatePrefix(I);for(let i of new Set(n))y.invalidatePrefix(`daily-report:detail:${i}:user:`),await w(`${T}${i}`);for(let i of new Set(o)){let h=se(i);h&&await w(`${v}${h}`)}},getUserIdByExternalId:oe,getDailyReportIdsByExternalId:me,getDailyReportIdsFirstPageByExternalId:k,getDailyReportsByBusinessDate:we,getDailyReportsByBusinessDateByExternalId:Bt,getDailyReportDetailById:Ee,getDailyReportDetailByIdByExternalId:Ut,getDraftLabelId:Ke,getAttachmentsByHubIds:Ue,getAttachmentForUser:Lt,markAttachmentMissing:$t,markAttachmentPresent:Pt,setStarStatus:Ot,setReadStatus:Yt,addComment:Ft,deleteComment:zt,createDailyReport:Kt,updateDailyReport:async(n,o,i,h)=>{let f=await He(e,n);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==o)throw new Error("Unauthorized");await e.transaction(async S=>{i.title!==void 0&&await Ve(S,n,{title:i.title,updatedAt:new Date,updatedBy:String(o)}),i.content!==void 0&&await ct(S,n,{body:i.content,updatedAt:new Date,updatedBy:String(o)})}),y.invalidate(`daily-report:detail:${n}`),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(I),await w(`${T}${n}`);let b=se(te(f[0].businessDate,"YYYY-MM-DD"));b&&(y.invalidatePrefix(`daily-report:date:${b}:user:`),await w(`${v}${b}`));let g=await Ee(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,o,{forceRefresh:!0});if(g){let S=await Be(),x=g.labels.some(J=>S.includes(J.id));await R(tt.parse({type:"report-update",reportHubId:g.reportHubId,report:g,clientTempId:h,recipientRawUserId:x?o:void 0}),"updateDailyReport")}},publishDailyReport:async(n,o,i)=>{let h=await He(e,n);if(!h.length)throw new Error("Not Found");if(h[0].userId!==o)throw new Error("Unauthorized");let f=await Ke();if(!f)return null;if(await pt(e,n,f),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(I),y.invalidatePrefix(Me),await w(De),h[0].businessDate){let S=se(te(h[0].businessDate,"YYYY-MM-DD"));S&&await w(`${v}${S}`)}let b=se(te(h[0].businessDate,"YYYY-MM-DD"));b&&y.invalidatePrefix(Q(b,o));let g=await Ee(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,o,{forceRefresh:!0});return g&&await R(rt.parse({type:"report-publish",reportHubId:g.reportHubId,report:g,clientTempId:i}),"publishDailyReport"),g??null},deleteDailyReport:async(n,o,i)=>{let h=await He(e,n);if(!h.length||h[0].deletedAt)throw new Error("Not Found");if(h[0].userId!==o)throw new Error("Unauthorized");if(await Ve(e,n,{deletedAt:new Date,deletedBy:String(o),updatedAt:new Date,updatedBy:String(o)}),y.invalidatePrefix(`daily-report:detail:${n}:user:`),y.invalidatePrefix(I),y.invalidatePrefix(Me),await w(De),h[0].businessDate){let f=se(te(h[0].businessDate,"YYYY-MM-DD"));f&&await w(`${v}${f}`)}await R(nt.parse({type:"report-delete",reportHubId:n,clientTempId:i,sourceType:h[0].sourceType}),"deleteDailyReport")},findDailyReportHubById:He,updateDailyReportHub:Ve,updateDailyReportInternal:ct,deleteDailyReportLabel:pt}}var $e=require("drizzle-orm");function kt(t){let e=[],r=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let s of r){let c=`daily_report_${s.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:c,name:s.name,description:s.description??`${s.name} daily report access`}),s.includeCommentResource!==!1&&e.push({resourceKey:`${c}_comment`,name:`${s.name} Comment`,description:`${s.name} daily report comment access`})}return e}async function kr(t,e,r){let s=t,m=e.TMResource,c=r.appKey,A=r.actor??"system:daily-report",y=new Date,L=r.resources??kt(r.sources);for(let u of L){let P=await s.select().from(m).where((0,$e.and)((0,$e.eq)(m.appKey,c),(0,$e.eq)(m.resourceKey,u.resourceKey)));(!P||P.length===0)&&await s.insert(m).values({appKey:c,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:y,createdBy:A,updatedAt:y,updatedBy:A})}}var Nr=le(1,"[DailyReportExternalSource]"),Lr=(t,e,r,s=Nr)=>{if(!t)return[];try{let m=JSON.parse(t);return Array.isArray(m)?m.map(r).filter(c=>c!==null):(s.warn(`Unexpected ${e} format: not an array`),[])}catch(m){return s.warn(`Failed to parse ${e}:`,m),[]}};var Pe=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function $r(t,e){let r=(0,l.mssqlSchema)(t),s=e.userTable,m=r.table("DailyReportHub",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,l.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,l.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,l.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(Pe.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,l.date)("business_date"),userId:(0,l.bigint)("user_id",{mode:"number"}),title:(0,l.nvarchar)("title",{length:200}),summary:(0,l.nvarchar)("summary",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,l.datetime2)("deleted_at"),deletedBy:(0,l.nvarchar)("deleted_by",{length:50})},p=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_pk`,columns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_user_id_fk`,columns:[p.userId],foreignColumns:[s.id]}),(0,l.index)(`${t}_DailyReportHub_business_date_index`).on(p.businessDate),(0,l.index)(`${t}_DailyReportHub_updated_at_index`).on(p.updatedAt),(0,l.index)(`${t}_DailyReportHub_source_index`).on(p.sourceType,p.sourceId),(0,l.index)(`${t}_DailyReportHub_user_id_index`).on(p.userId),(0,l.index)(`${t}_DailyReportHub_business_date_id_index`).on((0,Pe.desc)(p.businessDate),(0,Pe.desc)(p.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(p.deletedAt)]),c=r.table("DailyReportInternal",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}),metadata:(0,l.nvarchar)("metadata",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportInternal_pk`,columns:[p.hubId]}),(0,l.foreignKey)({name:`${t}_DailyReportInternal_hub_id_fk`,columns:[p.hubId],foreignColumns:[m.id]})]),A=r.table("DailyReportComment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportComment_pk`,columns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_hub_id_fk`,columns:[p.hubId],foreignColumns:[m.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[p.userId],foreignColumns:[s.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(p.hubId)]),y=r.table("DailyReportLabel",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}),name:(0,l.nvarchar)("name",{length:50}).notNull(),color:(0,l.nvarchar)("color",{length:20}),sortOrder:(0,l.int)("sort_order"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportLabel_pk`,columns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportLabel_user_id_fk`,columns:[p.userId],foreignColumns:[s.id]})]),L=r.table("DailyReportHub_Label",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,l.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_Label_pk`,columns:[p.hubId,p.labelId]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_hub_id_fk`,columns:[p.hubId],foreignColumns:[m.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[p.labelId],foreignColumns:[y.id]})]),u=r.table("DailyReportUserStatus",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,l.bit)("is_read").default(!1).notNull(),isStarred:(0,l.bit)("is_starred").default(!1).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportUserStatus_pk`,columns:[p.hubId,p.userId]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_hub_id_fk`,columns:[p.hubId],foreignColumns:[m.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[p.userId],foreignColumns:[s.id]})]),P=r.table("DailyReportAttachment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),uploadedBy:(0,l.bigint)("uploaded_by",{mode:"number"}),sourceKey:(0,l.nvarchar)("source_key",{length:200}).notNull(),fileName:(0,l.nvarchar)("file_name",{length:255}).notNull(),filePath:(0,l.nvarchar)("file_path",{length:"max"}).notNull(),fileType:(0,l.nvarchar)("file_type",{length:100}),fileSize:(0,l.bigint)("file_size",{mode:"number"}),objectCheckedAt:(0,l.datetime2)("object_checked_at"),objectMissingAt:(0,l.datetime2)("object_missing_at"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},p=>[(0,l.primaryKey)({name:`${t}_DailyReportAttachment_pk`,columns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_hub_id_fk`,columns:[p.hubId],foreignColumns:[m.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[p.uploadedBy],foreignColumns:[s.id]}),(0,l.uniqueIndex)(`${t}_DailyReportAttachment_source_unique`).on(p.hubId,p.sourceKey),(0,l.index)(`${t}_DailyReportAttachment_hub_id_index`).on(p.hubId,p.createdAt)]);return{hub:m,internal:c,comment:A,attachment:P,label:y,hubLabel:L,userStatus:u}}function Pr(t){let e=Ge(t.redis),r=new xe({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),s=ot({...t,cache:r,epochs:e}),m=new ke({redis:t.redis,streamKey:s.streamKey,cache:r,logger:t.logger}),c=it({authenticate:t.authenticate,resolveVisibleSourceTypes:t.resolveVisibleSourceTypes,service:s,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:m,streamKey:s.streamKey,loginRedirectPath:t.loginRedirectPath,enableDevCacheClear:t.enableDevCacheClear,logger:t.logger});return{service:s,cache:r,epochs:e,sseReader:m,streamKey:s.streamKey,knownSourceTypes:[...new Set(["Internal",...(t.externalSources??[]).map(A=>A.sourceType)])],...c}}0&&(module.exports={DailyReportSseReader,DailyReportViewerScope,SqlResultCache,asciiFallbackFileName,buildVisibleSourceTypeCondition,computeSourceTypeDigest,computeViewerScopeDigest,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,deniesEverySourceType,encodeRfc8187,formatDateValue,generateETag,isSourceTypeVisible,isStreamIdLte,jsonResponseWithETag,normalizeVisibleSourceTypes,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
|
|
14
|
+
`,z=te!=="0-0"?`id: ${te}
|
|
15
|
+
${x}`:x;w.enqueue(Z.encode(z))}if(M)try{let x=await p?.getClient();if(x){let z=await x.xRange(S,M,"+",{COUNT:1e3});for(let X of z)X.id!==M&&(Q!==null&&Ce(Q,X.id)||(Ce(X.id,te)||(te=X.id),re(X.id,X.message)))}}catch(x){B.error(`[SSE:${T}] catch-up xRange error:`,x)}},cancel(){j()}});return new Response(Se,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}},attachment:{loader:async({request:I,params:H})=>{let C=null,T=(_,$,D)=>{let k=new Headers({"Content-Type":"application/json"});return D!==void 0&&k.set("Retry-After",String(D)),C&&k.append("Set-Cookie",C),new Response(JSON.stringify({error:{message:$}}),{status:_,headers:k})};try{let{user:_,cookie:$}=await e(I,{failureRedirect:null});if(C=$??null,!_)return T(401,"Unauthorized");if(I.method!=="GET"&&I.method!=="HEAD")return T(405,"Method not allowed");let D=t.attachmentIdCodec,k=t.readAttachment;if(!(D&&k))return T(404,"Attachment not found");let K=H.token??"",v=D.decode(K);if(v===null||!Number.isSafeInteger(v)||v<=0)return T(400,"Invalid attachment token");let M=await r.getUserIdByExternalId(_.id);if(!M)return T(403,"Forbidden");if(!F(M,Date.now()))return y.error(`429 attachment=${v} viewer=${M} reason=rate_limit`),T(429,"Too many requests",Ar);let Z=await pe(I),w=await r.getAttachmentForUser(Z,v,M);if(!w)return y.error(`404 attachment=${v} viewer=${M} reason=not_visible`),T(404,"Attachment not found");if(w.fileSize!=null&&w.fileSize>V)return y.error(`413 attachment=${v} viewer=${M} reason=db_size`),T(413,"Attachment too large");if(!U.tryAcquire())return y.error(`503 attachment=${v} viewer=${M} reason=concurrency`),T(503,"Too many concurrent downloads",Tr);let Y=!1,R=()=>{Y||(Y=!0,U.release())},O=!1;try{let j=I.method==="HEAD",ee=await k(w.filePath,{maxBytes:V,head:j,principal:a(M)});if(!ee.ok){let X=Mr(ee.reason);return ee.reason==="not_found"&&r.markAttachmentMissing(v).catch(Ie=>{y.error(`markAttachmentMissing failed attachment=${v} message=${Ie instanceof Error?Ie.message:"unknown"}`)}),y.error(`${X} attachment=${v} viewer=${M} reason=${ee.reason} code=${ee.code??"-"}`),T(X,Er[X]??"Attachment storage unavailable")}let re=mt(w.fileType)??mt(ee.contentType)??"application/octet-stream",Se=Cr.has(re),me=new URL(I.url).searchParams.get("download")==="1",te=Se?re:"application/octet-stream",Q=Se&&!me?"inline":"attachment",x=ee.size??ee.bytes.byteLength,z=new Headers({"Content-Type":te,"Content-Length":String(x),"Content-Disposition":`${Q}; filename="${Lt(w.fileName)}"; filename*=UTF-8''${Nt(w.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return C&&z.append("Set-Cookie",C),r.markAttachmentPresent(v).catch(X=>{y.error(`markAttachmentPresent failed attachment=${v} message=${X instanceof Error?X.message:"unknown"}`)}),y.info(`200 attachment=${v} viewer=${M} type=${te} disposition=${Q} bytes=${x}`),j?new Response(null,{status:200,headers:z}):(O=!0,new Response(Nr(ee.bytes,R,Sr),{status:200,headers:z}))}finally{O||R()}}catch(_){if(_ instanceof Response)throw _;return y.error(`500 attachment=? viewer=? reason=unexpected message=${_ instanceof Error?_.message:"unknown"}`),T(500,"Attachment request failed")}}}}}var i=require("drizzle-orm");var De=t=>(0,i.getColumns)(t),ne=(t,e)=>{if(!t)return null;let r=t instanceof Date?t:new Date(t);if(Number.isNaN(r.getTime()))return typeof t=="string"?t:null;let a=r.getFullYear(),p=a<0?`-${String(-a).padStart(4,"0")}`:String(a).padStart(4,"0"),m=String(r.getMonth()+1).padStart(2,"0"),S=String(r.getDate()).padStart(2,"0");if(e==="YYYY-MM-DD")return`${p}-${m}-${S}`;let h=String(r.getHours()).padStart(2,"0"),L=String(r.getMinutes()).padStart(2,"0"),u=String(r.getSeconds()).padStart(2,"0");return`${p}-${m}-${S} ${h}:${L}:${u}`};function ht(t){let{db:e,tables:r,userTable:a,resolveUserId:p,encodeUserId:m,redis:S,cache:h,epochs:L}=t,{hub:u,internal:B,comment:y,label:V,hubLabel:F,userStatus:U}=r,pe=t.externalSources??[],Ee=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],xe=Ee[0]??"\u4E0B\u66F8\u304D",ae=t.logger??ue(1,"[DailyReportService]"),ke="daily-report:ids",ft=t.idsTtlMs??18e4,we="daily-report:ids:epoch",I="daily-report:business-date:",H=t.businessDateTtlMs??3e5,C="daily-report:date-epoch:",T="daily-report:detail-epoch:",_=t.streamKey??"daily-report:sse-stream",$=t.streamMaxLen??1e4,D=n=>L.incrementEpoch(n),k=n=>pt(u.sourceType,n),K=(n,s)=>`${ke}:user:${n}:st:${s}`,v=n=>`${ke}:user:${n}:`,M=(n,s,o)=>`daily-report:date:${n}:user:${s}:st:${o}`,Z=(n,s)=>`daily-report:date:${n}:user:${s}:`,w=(n,s,o)=>`daily-report:detail:${n}:user:${s}:st:${o}`,Y=(n,s)=>`daily-report:detail:${n}:user:${s}:`,R=async(n,s)=>{let o=await S?.getClient();if(!o){ae.warn(`[SSE] Redis client unavailable (${s})`);return}let d=Date.now();try{await o.xAdd(_,"*",{data:JSON.stringify(n)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:$}});let f=Date.now()-d;f>1e3&&ae.warn(`[SSE] Slow publish (${s}): ${f}ms`)}catch(f){ae.error(`[SSE] Redis publish failed (${s}):`,f)}},O=n=>n==null||n===""?null:/^\d+$/.test(n)?m(Number(n)):n,j=()=>{let n={};for(let s of pe)n[`ext_${s.sourceType}`]=De(s.table);return n},ee=n=>{let s=n;for(let o of pe)s=s.leftJoin(o.table,(0,i.and)((0,i.eq)(u.sourceType,o.sourceType),(0,i.eq)(u.sourceIdNum,o.idColumn)));return s},re=(n,s,o)=>{let{hub:d,internal:f}=s,b=d.summary,g=[],A=null,E=null,J=null,q=null,W=null,ie=null,Ae=[],ge=pe.find(N=>N.sourceType===d.sourceType),Te=ge?s[`ext_${ge.sourceType}`]:void 0;if(ge&&Te){let N=ge.mapRow(Te);N.content!==void 0&&(b=N.content),N.employeeName!==void 0&&(ie=N.employeeName),N.category!==void 0&&(A=N.category),N.creationCategory!==void 0&&(E=N.creationCategory),N.visitTimeFrom!==void 0&&(J=N.visitTimeFrom),N.visitTimeTo!==void 0&&(q=N.visitTimeTo),N.customerName!==void 0&&(W=N.customerName),N.interviewers!==void 0&&(g=N.interviewers),N.comments!==void 0&&(Ae=N.comments)}else d.sourceType==="Internal"&&f&&(b=f.body);let be=(s.labels??[]).map(N=>({id:N.id,name:N.name,color:N.color})),se=s.comments??[],G=he(n.commentable,d.sourceType),oe=E?Ee.includes(E):!1,Xe=ye?.[0]??null;return oe&&Xe&&!be.some(N=>N.id===Xe)&&be.push({id:Xe,name:xe,color:null}),{reportHubId:d.id,date:ne(d.businessDate,"YYYY-MM-DD"),author:s.creatorName??O(d.createdBy)??"",userId:d.userId?m(d.userId):"",sourceType:d.sourceType??"Internal",createdAt:ne(d.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:ne(d.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:O(d.updatedBy),employeeName:ie??s.creatorName??O(d.createdBy),category:A,creationCategory:E,visitTimeFrom:J,visitTimeTo:q,customerName:W,interviewers:g,subject:d.title,content:b,comments:G?Ae:[],isRead:s.isRead??!1,isStarred:s.isStarred??!1,labels:be,commentItems:se.filter(N=>G||o!==void 0&&N.userId===o).map(N=>({...N,userId:m(N.userId),isMine:o?N.userId===o:!1})),attachments:s.attachments}},Se=async(n,s)=>{let o=(0,i.aliasedTable)(F,"draft_label"),d=await fe();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(o,(0,i.and)((0,i.eq)(o.hubId,u.id),(0,i.inArray)(o.labelId,d))).where((0,i.and)((0,i.isNull)(u.deletedAt),(0,i.or)((0,i.eq)(u.userId,s),(0,i.isNull)(u.userId),(0,i.isNull)(o.hubId)),k(n.visible))).orderBy((0,i.desc)(u.businessDate),(0,i.desc)(u.id))).map(b=>({...b,businessDate:ne(b.businessDate,"YYYY-MM-DD")}))},me=async(n,s,o)=>{let d=await z(s);if(!d)return[];if(Re(n.visible))return[];let f=(0,i.aliasedTable)(F,"draft_label"),b=await fe();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).top(o).from(u).leftJoin(f,(0,i.and)((0,i.eq)(f.hubId,u.id),(0,i.inArray)(f.labelId,b))).where((0,i.and)((0,i.isNull)(u.deletedAt),(0,i.or)((0,i.eq)(u.userId,d),(0,i.isNull)(u.userId),(0,i.isNull)(f.hubId)),k(n.visible))).orderBy((0,i.desc)(u.businessDate),(0,i.desc)(u.id))).map(A=>({...A,businessDate:ne(A.businessDate,"YYYY-MM-DD")}))},te=async(n,s)=>{let o=await ee(e.select({hub:De(u),internal:De(B),creatorName:a.displayName,...j()}).from(u)).leftJoin(B,(0,i.eq)(u.id,B.hubId)).leftJoin(a,(0,i.eq)(u.userId,a.id)).where((0,i.and)((0,i.eq)(u.businessDate,i.sql`${s}`),(0,i.isNull)(u.deletedAt),k(n.visible))).orderBy((0,i.desc)(u.id)),d=await Fe(o.map(f=>f.hub.id));return o.map(f=>re(n,{...f,attachments:d.get(f.hub.id)??[]}))},Q=n=>`${I}${n}`,x=new Map,z=async n=>{if(!t.disableUserIdCache&&x.has(n))return x.get(n)??null;let s=await p(n);return s!==null&&!t.disableUserIdCache&&x.set(n,s),s},X=async(n,s,{forceRefresh:o=!1,snapshot:d=!1,ttlMsOverride:f}={})=>{let b=await z(s);if(!b)return[];if(Re(n.visible))return[];let g=K(b,Me(n));return h.getOrFetch({cacheKey:g,fetcher:async()=>await Se(n,b),forceRefresh:o,snapshot:d,ttlMsOverride:f??ft,epochKey:we,refreshAheadRatio:.5})},Ie=(n,s,{forceRefresh:o=!1,snapshot:d=!1,ttlMsOverride:f}={})=>{let b=le(s);return b?Re(n.visible)?Promise.resolve([]):h.getOrFetch({cacheKey:`${Q(b)}:st:${Me(n)}`,fetcher:()=>te(n,b),forceRefresh:o,snapshot:d,ttlMsOverride:f??H}):Promise.resolve([])},ye=null,Ne=async()=>(ye!==null||(ye=(await e.select({id:V.id}).from(V).where((0,i.inArray)(V.name,Ee)).orderBy(V.id)).map(s=>s.id)),ye),fe=async()=>{let n=await Ne();return n.length>0?n:[-1]},Je=async()=>{let n=await Ne();if(n.length===0)return null;let[s]=await e.select({id:V.id}).top(1).from(V).where((0,i.eq)(V.name,xe));return s?.id??n[0]},Pt=(n,s)=>s!=null?"absent":n!=null?"present":"unknown",Fe=async n=>{let s=new Map,o=r.attachment,d=t.attachmentIdCodec;if(n.length===0||!o||!d)return s;let f=await e.select({id:o.id,hubId:o.hubId,fileName:o.fileName,fileType:o.fileType,fileSize:o.fileSize,createdAt:o.createdAt,objectCheckedAt:o.objectCheckedAt,objectMissingAt:o.objectMissingAt}).from(o).where((0,i.inArray)(o.hubId,n)).orderBy((0,i.asc)(o.createdAt),(0,i.asc)(o.id));for(let b of f){let g={id:d.encode(Number(b.id)),fileName:String(b.fileName),fileType:b.fileType?String(b.fileType):null,fileSize:b.fileSize!=null?Number(b.fileSize):null,createdAt:ne(b.createdAt,"YYYY-MM-DD HH:mm:ss"),state:Pt(b.objectCheckedAt,b.objectMissingAt)},A=s.get(Number(b.hubId));A?A.push(g):s.set(Number(b.hubId),[g])}return s},Bt=async(n,s,o)=>{let d=r.attachment;if(!d||Re(n.visible))return null;let f=await fe(),b=(0,i.aliasedTable)(F,"draft_label");return(await e.select({fileName:d.fileName,filePath:d.filePath,fileType:d.fileType,fileSize:d.fileSize}).top(1).from(d).innerJoin(u,(0,i.eq)(u.id,d.hubId)).leftJoin(b,(0,i.and)((0,i.eq)(b.hubId,u.id),(0,i.inArray)(b.labelId,f))).where((0,i.and)((0,i.eq)(d.id,s),(0,i.isNull)(u.deletedAt),(0,i.or)((0,i.eq)(u.userId,o),(0,i.isNull)(b.hubId)),k(n.visible))))[0]??null},Ut=async n=>{let s=r.attachment;if(!s)return;let o=new Date;try{await e.update(s).set({objectCheckedAt:o,objectMissingAt:o,updatedAt:o}).where((0,i.eq)(s.id,n))}catch(d){ae.error("markAttachmentMissing failed",d)}},Ht=async n=>{let s=r.attachment;if(!s)return;let o=new Date;try{await e.update(s).set({objectCheckedAt:o,objectMissingAt:null,updatedAt:o}).where((0,i.eq)(s.id,n))}catch(d){ae.error("markAttachmentPresent failed",d)}},Ot=async(n,s,o,{forceRefresh:d=!1,snapshot:f=!1,ttlMsOverride:b}={})=>{let g=await z(o);if(!g)return[];let A=le(s);if(!A)return[];if(Re(n.visible))return[];let E=M(A,g,Me(n));return h.getOrFetch({cacheKey:E,fetcher:async()=>{let J=await fe(),q=(0,i.aliasedTable)(F,"draft_label"),W=await ee(e.select({hub:De(u),internal:De(B),isRead:U.isRead,isStarred:U.isStarred,creatorName:a.displayName,...j()}).from(u)).leftJoin(B,(0,i.eq)(u.id,B.hubId)).leftJoin(U,(0,i.and)((0,i.eq)(u.id,U.hubId),(0,i.eq)(U.userId,g))).leftJoin(q,(0,i.and)((0,i.eq)(q.hubId,u.id),(0,i.inArray)(q.labelId,J))).leftJoin(a,(0,i.eq)(u.userId,a.id)).where((0,i.and)((0,i.eq)(u.businessDate,i.sql`${A}`),(0,i.isNull)(u.deletedAt),(0,i.or)((0,i.eq)(u.userId,g),(0,i.isNull)(q.hubId)),k(n.visible))).orderBy((0,i.desc)(u.id));if(W.length===0)return[];let ie=W.map(G=>G.hub.id),Ae=await e.select({hubId:F.hubId,id:V.id,name:V.name,color:V.color}).from(F).innerJoin(V,(0,i.eq)(F.labelId,V.id)).where((0,i.inArray)(F.hubId,ie)),ge=await e.select({hubId:y.hubId,id:y.id,body:y.body,createdAt:y.createdAt,userId:y.userId,userName:a.displayName}).from(y).leftJoin(a,(0,i.eq)(y.userId,a.id)).where((0,i.inArray)(y.hubId,ie)).orderBy((0,i.asc)(y.createdAt)),Te=await Fe(ie),be=new Map,se=new Map;for(let G of Ae){let oe=be.get(G.hubId);oe||(oe=[],be.set(G.hubId,oe)),oe.push({id:G.id,name:G.name,color:G.color})}for(let G of ge){let oe=se.get(G.hubId);oe||(oe=[],se.set(G.hubId,oe)),oe.push({id:G.id,content:G.body,createdAt:ne(G.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:G.userId,userName:G.userName||""})}return W.map(G=>{let oe=G.hub.id;return re(n,{...G,attachments:Te.get(oe)??[],labels:be.get(oe)||[],comments:se.get(oe)||[]},g)})},forceRefresh:d,snapshot:f,ttlMsOverride:b??H,epochKey:`${C}${A}`})},Le=async(n,s,o,{forceRefresh:d=!1,snapshot:f=!1,ttlMsOverride:b}={})=>{if(Re(n.visible))return null;let g=w(s,o,Me(n));return(await h.getOrFetch({cacheKey:g,fetcher:async()=>{let E=await fe(),J=(0,i.aliasedTable)(F,"draft_label"),q=await ee(e.select({hub:De(u),internal:De(B),isRead:U.isRead,isStarred:U.isStarred,creatorName:a.displayName,...j()}).from(u)).leftJoin(B,(0,i.eq)(u.id,B.hubId)).leftJoin(U,(0,i.and)((0,i.eq)(u.id,U.hubId),(0,i.eq)(U.userId,o))).leftJoin(J,(0,i.and)((0,i.eq)(J.hubId,u.id),(0,i.inArray)(J.labelId,E))).leftJoin(a,(0,i.eq)(u.userId,a.id)).where((0,i.and)((0,i.eq)(u.id,s),(0,i.isNull)(u.deletedAt),(0,i.or)((0,i.eq)(u.userId,o),(0,i.isNull)(J.hubId)),k(n.visible)));if(q.length===0)return[];let W=q[0].hub.id,ie=await e.select({id:V.id,name:V.name,color:V.color}).from(F).innerJoin(V,(0,i.eq)(F.labelId,V.id)).where((0,i.eq)(F.hubId,W)),Ae=await e.select({id:y.id,body:y.body,createdAt:y.createdAt,userId:y.userId,userName:a.displayName}).from(y).leftJoin(a,(0,i.eq)(y.userId,a.id)).where((0,i.eq)(y.hubId,W)).orderBy((0,i.asc)(y.createdAt)),ge=await Fe([W]),Te=ie.map(se=>({id:se.id,name:se.name,color:se.color})),be=Ae.map(se=>({id:se.id,content:se.body,createdAt:ne(se.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:se.userId,userName:se.userName||""}));return[re(n,{...q[0],attachments:ge.get(W)??[],labels:Te,comments:be},o)]},forceRefresh:d,snapshot:f,ttlMsOverride:b??H,epochKey:`${T}${s}`}))[0]??null},Yt=async(n,s,o,d={})=>{let f=await z(o);return f?Le(n,s,f,d):null},Ft=async(n,s)=>{let o=await fe(),d=(0,i.aliasedTable)(F,"draft_label"),[f]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt}).top(1).from(u).leftJoin(d,(0,i.and)((0,i.eq)(d.hubId,u.id),(0,i.inArray)(d.labelId,o))).where((0,i.and)((0,i.eq)(u.id,n),(0,i.or)((0,i.eq)(u.userId,s),(0,i.isNull)(d.hubId))));return f??null},Ge=async(n,s,o)=>{let d=await Ft(s,o);if(!d||d.deletedAt||!he(n.visible,d.sourceType))throw new Error("Not Found")},qt=async(n,s,o,d,f,b)=>{await Ge(n,o,s);let g=await e.select().top(1).from(U).where((0,i.and)((0,i.eq)(U.hubId,o),(0,i.eq)(U.userId,s))),A;if(g.length>0?g[0].isStarred!==f?A=(await e.update(U).set({isStarred:f,updatedAt:new Date,updatedBy:String(s)}).output().where((0,i.and)((0,i.eq)(U.hubId,o),(0,i.eq)(U.userId,s))))[0]:A=g[0]:A=(await e.insert(U).output().values({hubId:o,userId:s,isStarred:f,isRead:!1,createdAt:new Date,createdBy:String(s),updatedAt:new Date,updatedBy:String(s)}))[0],d){let E=le(d);E&&(h.invalidatePrefix(Z(E,s)),await D(`${C}${E}`))}return h.invalidate(`daily-report:detail:${o}`),h.invalidatePrefix(Y(o,s)),await D(`${T}${o}`),await R(ze.parse({type:"status-update",reportHubId:o,recipientRawUserId:s,statusType:"star",value:f,clientTempId:b}),"setStarStatus"),A},zt=async(n,s,o,d,f,b)=>{await Ge(n,o,s);let g=await e.select().top(1).from(U).where((0,i.and)((0,i.eq)(U.hubId,o),(0,i.eq)(U.userId,s))),A;if(g.length>0?g[0].isRead!==f?A=(await e.update(U).set({isRead:f,updatedAt:new Date,updatedBy:String(s)}).output().where((0,i.and)((0,i.eq)(U.hubId,o),(0,i.eq)(U.userId,s))))[0]:A=g[0]:A=(await e.insert(U).output().values({hubId:o,userId:s,isRead:f,isStarred:!1,createdAt:new Date,createdBy:String(s),updatedAt:new Date,updatedBy:String(s)}))[0],d){let E=le(d);E&&(h.invalidatePrefix(Z(E,s)),await D(`${C}${E}`))}return h.invalidate(`daily-report:detail:${o}`),h.invalidatePrefix(Y(o,s)),await D(`${T}${o}`),await R(ze.parse({type:"status-update",reportHubId:o,recipientRawUserId:s,statusType:"read",value:f,clientTempId:b}),"setReadStatus"),A},bt=async(n,s)=>{if(s===null)return;let o=await fe(),[d]=await e.select({hubId:F.hubId}).top(1).from(F).where((0,i.and)((0,i.eq)(F.hubId,n),(0,i.inArray)(F.labelId,o)));return d?s:void 0},Vt=async(n,s,o,d,f,b)=>{let[g]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt,userId:u.userId}).top(1).from(u).where((0,i.eq)(u.id,o));if(!g||g.deletedAt)throw new Error("Not Found");if(await Ge(n,o,s),!he(n.commentable,g.sourceType))throw new Error("Comments are restricted by the viewer's comment permission");if(g.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let A=await bt(o,g.userId),[E]=await e.insert(y).output().values({hubId:o,userId:s,body:d,createdAt:new Date,createdBy:String(s),updatedAt:new Date,updatedBy:String(s)}),[J]=await e.select({displayName:a.displayName}).top(1).from(a).where((0,i.eq)(a.id,s)),q=J?.displayName??"Unknown";if(f){let ie=le(f);ie&&(h.invalidatePrefix(`daily-report:date:${ie}:user:`),await D(`${C}${ie}`))}h.invalidate(`daily-report:detail:${o}`),h.invalidatePrefix(`daily-report:detail:${o}:user:`),await D(`${T}${o}`);let W={id:E.id,userId:m(E.userId),userName:q,content:E.body,createdAt:ne(E.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await R(at.parse({type:"comment-add",reportHubId:o,comment:W,clientTempId:b,recipientRawUserId:A,sourceType:g.sourceType}),"addComment"),W},Kt=async(n,s)=>await n.select().top(1).from(y).where((0,i.eq)(y.id,s)),jt=async(n,s,o,d,f,b)=>{let g=await Kt(e,d);if(g.length===0)throw new Error("Not Found");if(g[0].hubId!==o)throw new Error("Not Found");let[A]=await e.select({userId:u.userId,sourceType:u.sourceType}).top(1).from(u).where((0,i.eq)(u.id,g[0].hubId));if(!(A&&he(n.visible,A.sourceType)))throw new Error("Not Found");if(g[0].userId!==s)throw new Error("Unauthorized");let E=await bt(o,A.userId);if(await e.delete(y).where((0,i.eq)(y.id,d)),f){let J=le(f);J&&(h.invalidatePrefix(`daily-report:date:${J}:user:`),await D(`${C}${J}`))}h.invalidate(`daily-report:detail:${o}`),h.invalidatePrefix(`daily-report:detail:${o}:user:`),await D(`${T}${o}`),await R(it.parse({type:"comment-delete",reportHubId:o,commentId:d,clientTempId:b,recipientRawUserId:E,sourceType:A?.sourceType}),"deleteComment")},Jt=async(n,s,o)=>{ae.info("createDailyReport called",{userId:n,businessDate:s});let[d]=await e.select({displayName:a.displayName}).from(a).where((0,i.eq)(a.id,n)),f=d?.displayName??m(n);try{let b=await e.transaction(async E=>{ae.info("Starting transaction");let J=`internal-temp-${Date.now()}-${Math.random()}`,[q]=await E.insert(u).output().values({sourceType:"Internal",sourceId:J,businessDate:new Date(s),userId:n,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)});await E.update(u).set({sourceId:String(q.id)}).where((0,i.eq)(u.id,q.id)),ae.info("Hub created",q),await E.insert(B).values({hubId:q.id,body:"",createdAt:new Date,createdBy:String(n),updatedAt:new Date,updatedBy:String(n)}),ae.info("Internal created"),ae.info("Calling getDraftLabelId");let W=await Je();ae.info("draftLabelId",W);let ie=[];return W&&(await E.insert(F).values({hubId:q.id,labelId:W,createdAt:new Date,createdBy:String(n)}),ie.push({id:W,name:xe,color:null})),ae.info("Label assigned"),{reportHubId:q.id,date:s,createdAt:ne(q.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:m(n),sourceType:"Internal",employeeName:f,updatedBy:m(n),updatedAt:ne(q.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:q.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:ie,commentItems:[],attachments:[]}}),g=le(s);g&&h.invalidatePrefix(Z(g,n)),h.invalidatePrefix(I),h.invalidatePrefix(v(n)),await D(we),g&&await D(`${C}${g}`);let A=await Le(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),b.reportHubId,n,{forceRefresh:!0});if(A){let E=await Ne(),J=A.labels.some(q=>E.includes(q.id));await R(st.parse({type:"report-create",reportHubId:A.reportHubId,report:A,clientTempId:o,recipientRawUserId:J?n:void 0}),"createDailyReport")}return A??b}catch(b){throw ae.error("Error in createDailyReport",b),b}},qe=async(n,s)=>await n.select().top(1).from(u).where((0,i.eq)(u.id,s)),Qe=async(n,s,o)=>{await n.update(u).set(o).where((0,i.eq)(u.id,s))},gt=async(n,s,o)=>{await n.update(B).set(o).where((0,i.eq)(B.hubId,s))},Rt=async(n,s,o)=>{await n.delete(F).where((0,i.and)((0,i.eq)(F.hubId,s),(0,i.eq)(F.labelId,o)))};return{streamKey:_,streamMaxLen:$,clearCache:async()=>{h.clearAll(),x.clear(),ye=null,L&&await D(we),ae.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(n,s)=>{h.invalidatePrefix(I);for(let o of new Set(n))h.invalidatePrefix(`daily-report:detail:${o}:user:`),await D(`${T}${o}`);for(let o of new Set(s)){let d=le(o);d&&await D(`${C}${d}`)}},getUserIdByExternalId:z,getDailyReportIdsByExternalId:X,getDailyReportIdsFirstPageByExternalId:me,getDailyReportsByBusinessDate:Ie,getDailyReportsByBusinessDateByExternalId:Ot,getDailyReportDetailById:Le,getDailyReportDetailByIdByExternalId:Yt,getDraftLabelId:Je,getAttachmentsByHubIds:Fe,getAttachmentForUser:Bt,markAttachmentMissing:Ut,markAttachmentPresent:Ht,setStarStatus:qt,setReadStatus:zt,addComment:Vt,deleteComment:jt,createDailyReport:Jt,updateDailyReport:async(n,s,o,d)=>{let f=await qe(e,n);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==s)throw new Error("Unauthorized");await e.transaction(async A=>{o.title!==void 0&&await Qe(A,n,{title:o.title,updatedAt:new Date,updatedBy:String(s)}),o.content!==void 0&&await gt(A,n,{body:o.content,updatedAt:new Date,updatedBy:String(s)})}),h.invalidate(`daily-report:detail:${n}`),h.invalidatePrefix(`daily-report:detail:${n}:user:`),h.invalidatePrefix(I),await D(`${T}${n}`);let b=le(ne(f[0].businessDate,"YYYY-MM-DD"));b&&(h.invalidatePrefix(`daily-report:date:${b}:user:`),await D(`${C}${b}`));let g=await Le(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,s,{forceRefresh:!0});if(g){let A=await Ne(),E=g.labels.some(J=>A.includes(J.id));await R(ot.parse({type:"report-update",reportHubId:g.reportHubId,report:g,clientTempId:d,recipientRawUserId:E?s:void 0}),"updateDailyReport")}},publishDailyReport:async(n,s,o)=>{let d=await qe(e,n);if(!d.length)throw new Error("Not Found");if(d[0].userId!==s)throw new Error("Unauthorized");let f=await Je();if(!f)return null;if(await Rt(e,n,f),h.invalidatePrefix(`daily-report:detail:${n}:user:`),h.invalidatePrefix(I),h.invalidatePrefix(ke),await D(we),d[0].businessDate){let A=le(ne(d[0].businessDate,"YYYY-MM-DD"));A&&await D(`${C}${A}`)}let b=le(ne(d[0].businessDate,"YYYY-MM-DD"));b&&h.invalidatePrefix(Z(b,s));let g=await Le(ce.unrestricted("post-write self read: the writer always sees the row they just wrote"),n,s,{forceRefresh:!0});return g&&await R(lt.parse({type:"report-publish",reportHubId:g.reportHubId,report:g,clientTempId:o}),"publishDailyReport"),g??null},deleteDailyReport:async(n,s,o)=>{let d=await qe(e,n);if(!d.length||d[0].deletedAt)throw new Error("Not Found");if(d[0].userId!==s)throw new Error("Unauthorized");if(await Qe(e,n,{deletedAt:new Date,deletedBy:String(s),updatedAt:new Date,updatedBy:String(s)}),h.invalidatePrefix(`daily-report:detail:${n}:user:`),h.invalidatePrefix(I),h.invalidatePrefix(ke),await D(we),d[0].businessDate){let f=le(ne(d[0].businessDate,"YYYY-MM-DD"));f&&await D(`${C}${f}`)}await R(ut.parse({type:"report-delete",reportHubId:n,clientTempId:o,sourceType:d[0].sourceType}),"deleteDailyReport")},findDailyReportHubById:qe,updateDailyReportHub:Qe,updateDailyReportInternal:gt,deleteDailyReportLabel:Rt}}var Oe=require("drizzle-orm");function $t(t){let e=[],r=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let a of r){let m=`daily_report_${a.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:m,name:a.name,description:a.description??`${a.name} daily report access`}),a.includeCommentResource!==!1&&e.push({resourceKey:`${m}_comment`,name:`${a.name} Comment`,description:`${a.name} daily report comment access`})}return e}async function Pr(t,e,r){let a=t,p=e.TMResource,m=r.appKey,S=r.actor??"system:daily-report",h=new Date,L=r.resources??$t(r.sources);for(let u of L){let B=await a.select().from(p).where((0,Oe.and)((0,Oe.eq)(p.appKey,m),(0,Oe.eq)(p.resourceKey,u.resourceKey)));(!B||B.length===0)&&await a.insert(p).values({appKey:m,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:h,createdBy:S,updatedAt:h,updatedBy:S})}}var Br=ue(1,"[DailyReportExternalSource]"),Ur=(t,e,r,a=Br)=>{if(!t)return[];try{let p=JSON.parse(t);return Array.isArray(p)?p.map(r).filter(m=>m!==null):(a.warn(`Unexpected ${e} format: not an array`),[])}catch(p){return a.warn(`Failed to parse ${e}:`,p),[]}};var Ye=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function Hr(t,e){let r=(0,l.mssqlSchema)(t),a=e.userTable,p=r.table("DailyReportHub",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),sourceType:(0,l.nvarchar)("source_type",{length:20}).notNull(),sourceId:(0,l.nvarchar)("source_id",{length:100}).notNull(),sourceIdNum:(0,l.bigint)("source_id_num",{mode:"number"}).generatedAlwaysAs(Ye.sql`TRY_CAST(source_id AS BIGINT)`),businessDate:(0,l.date)("business_date"),userId:(0,l.bigint)("user_id",{mode:"number"}),title:(0,l.nvarchar)("title",{length:200}),summary:(0,l.nvarchar)("summary",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull(),deletedAt:(0,l.datetime2)("deleted_at"),deletedBy:(0,l.nvarchar)("deleted_by",{length:50})},y=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_pk`,columns:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_user_id_fk`,columns:[y.userId],foreignColumns:[a.id]}),(0,l.index)(`${t}_DailyReportHub_business_date_index`).on(y.businessDate),(0,l.index)(`${t}_DailyReportHub_updated_at_index`).on(y.updatedAt),(0,l.index)(`${t}_DailyReportHub_source_index`).on(y.sourceType,y.sourceId),(0,l.index)(`${t}_DailyReportHub_user_id_index`).on(y.userId),(0,l.index)(`${t}_DailyReportHub_business_date_id_index`).on((0,Ye.desc)(y.businessDate),(0,Ye.desc)(y.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(y.deletedAt)]),m=r.table("DailyReportInternal",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}),metadata:(0,l.nvarchar)("metadata",{length:"max"}),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportInternal_pk`,columns:[y.hubId]}),(0,l.foreignKey)({name:`${t}_DailyReportInternal_hub_id_fk`,columns:[y.hubId],foreignColumns:[p.id]})]),S=r.table("DailyReportComment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),body:(0,l.nvarchar)("body",{length:"max"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportComment_pk`,columns:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_hub_id_fk`,columns:[y.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[y.userId],foreignColumns:[a.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(y.hubId)]),h=r.table("DailyReportLabel",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}),name:(0,l.nvarchar)("name",{length:50}).notNull(),color:(0,l.nvarchar)("color",{length:20}),sortOrder:(0,l.int)("sort_order"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportLabel_pk`,columns:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportLabel_user_id_fk`,columns:[y.userId],foreignColumns:[a.id]})]),L=r.table("DailyReportHub_Label",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),labelId:(0,l.bigint)("label_id",{mode:"number"}).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_Label_pk`,columns:[y.hubId,y.labelId]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_hub_id_fk`,columns:[y.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[y.labelId],foreignColumns:[h.id]})]),u=r.table("DailyReportUserStatus",{hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),userId:(0,l.bigint)("user_id",{mode:"number"}).notNull(),isRead:(0,l.bit)("is_read").default(!1).notNull(),isStarred:(0,l.bit)("is_starred").default(!1).notNull(),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportUserStatus_pk`,columns:[y.hubId,y.userId]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_hub_id_fk`,columns:[y.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[y.userId],foreignColumns:[a.id]})]),B=r.table("DailyReportAttachment",{id:(0,l.bigint)("id",{mode:"number"}).identity().notNull(),hubId:(0,l.bigint)("hub_id",{mode:"number"}).notNull(),uploadedBy:(0,l.bigint)("uploaded_by",{mode:"number"}),sourceKey:(0,l.nvarchar)("source_key",{length:200}).notNull(),fileName:(0,l.nvarchar)("file_name",{length:255}).notNull(),filePath:(0,l.nvarchar)("file_path",{length:"max"}).notNull(),fileType:(0,l.nvarchar)("file_type",{length:100}),fileSize:(0,l.bigint)("file_size",{mode:"number"}),objectCheckedAt:(0,l.datetime2)("object_checked_at"),objectMissingAt:(0,l.datetime2)("object_missing_at"),createdAt:(0,l.datetime2)("created_at").notNull(),createdBy:(0,l.nvarchar)("created_by",{length:50}).notNull(),updatedAt:(0,l.datetime2)("updated_at").notNull(),updatedBy:(0,l.nvarchar)("updated_by",{length:50}).notNull()},y=>[(0,l.primaryKey)({name:`${t}_DailyReportAttachment_pk`,columns:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_hub_id_fk`,columns:[y.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[y.uploadedBy],foreignColumns:[a.id]}),(0,l.uniqueIndex)(`${t}_DailyReportAttachment_source_unique`).on(y.hubId,y.sourceKey),(0,l.index)(`${t}_DailyReportAttachment_hub_id_index`).on(y.hubId,y.createdAt)]);return{hub:p,internal:m,comment:S,attachment:B,label:h,hubLabel:L,userStatus:u}}function Or(t){let e=tt(t.redis),r=new Pe({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),a=ht({...t,cache:r,epochs:e}),p=new Be({redis:t.redis,streamKey:a.streamKey,cache:r,logger:t.logger}),m=yt({authenticate:t.authenticate,resolveVisibleSourceTypes:t.resolveVisibleSourceTypes,service:a,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:p,streamKey:a.streamKey,loginRedirectPath:t.loginRedirectPath,enableDevCacheClear:t.enableDevCacheClear,logger:t.logger});return{service:a,cache:r,epochs:e,sseReader:p,streamKey:a.streamKey,knownSourceTypes:[...new Set(["Internal",...(t.externalSources??[]).map(S=>S.sourceType)])],...m}}0&&(module.exports={DailyReportSseReader,DailyReportViewerScope,SqlResultCache,asciiFallbackFileName,buildVisibleSourceTypeCondition,computeSourceTypeDigest,computeViewerScopeDigest,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,deniesEverySourceType,encodeRfc8187,formatDateValue,generateETag,isSourceTypeVisible,isStreamIdLte,jsonResponseWithETag,normalizeVisibleSourceTypes,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
|
|
16
16
|
//# sourceMappingURL=server.js.map
|