@aiquants/daily-report 0.8.0 → 0.9.1

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.
Files changed (58) hide show
  1. package/README.md +5 -0
  2. package/dist/client.d.mts +86 -7
  3. package/dist/client.d.ts +86 -7
  4. package/dist/client.js +5 -5
  5. package/dist/client.js.map +1 -1
  6. package/dist/client.mjs +5 -5
  7. package/dist/client.mjs.map +1 -1
  8. package/dist/index.d.mts +40 -2
  9. package/dist/index.d.ts +40 -2
  10. package/dist/index.js +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/index.mjs +1 -1
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/server.d.mts +13 -0
  15. package/dist/server.d.ts +13 -0
  16. package/dist/server.js +8 -7
  17. package/dist/server.js.map +1 -1
  18. package/dist/server.mjs +8 -7
  19. package/dist/server.mjs.map +1 -1
  20. package/dist/{sse-schema-Df49KA7B.d.mts → sse-schema-BiUnufrI.d.mts} +12 -0
  21. package/dist/{sse-schema-RHckD7TS.d.ts → sse-schema-YZh7Pz7i.d.ts} +12 -0
  22. package/dist/styles/daily-report.standalone.css +1 -1
  23. package/package.json +3 -3
  24. package/src/client/components/daily-report-comment-item.tsx +6 -1
  25. package/src/client/components/daily-report-detail-list.tsx +65 -34
  26. package/src/client/components/daily-report-edit-form.tsx +6 -0
  27. package/src/client/components/daily-report-list.tsx +88 -55
  28. package/src/client/components/daily-report-page.tsx +8 -3
  29. package/src/client/components/daily-report-resolved-content.tsx +5 -3
  30. package/src/client/components/report-views.spec.tsx +37 -2
  31. package/src/client/config-context.tsx +18 -0
  32. package/src/client/contexts/daily-report-action-context.spec.tsx +74 -0
  33. package/src/client/contexts/daily-report-action-context.tsx +98 -35
  34. package/src/client/contexts/daily-report-error-context.spec.tsx +66 -0
  35. package/src/client/contexts/daily-report-error-context.tsx +98 -0
  36. package/src/client/hooks/use-daily-report.spec.ts +107 -2
  37. package/src/client/hooks/use-daily-report.ts +37 -3
  38. package/src/client/streaming/daily-report-ids-stream-client.spec.ts +64 -1
  39. package/src/client/streaming/daily-report-ids-stream-client.ts +80 -2
  40. package/src/client/utils/constants.ts +11 -1
  41. package/src/client.ts +1 -0
  42. package/src/server/handlers.action.spec.ts +44 -0
  43. package/src/server/handlers.ids-stream.spec.ts +53 -1
  44. package/src/server/handlers.ts +81 -5
  45. package/src/server/service.spec.ts +83 -7
  46. package/src/server/service.ts +60 -3
  47. package/src/server/test-helpers/handlers-config.ts +9 -1
  48. package/src/server.spec.ts +49 -0
  49. package/src/server.ts +7 -0
  50. package/src/shared/business-date.spec.ts +22 -1
  51. package/src/shared/business-date.ts +20 -0
  52. package/src/shared/comment-adapter.spec.ts +38 -0
  53. package/src/shared/comment-adapter.ts +9 -7
  54. package/src/shared/ids-stream.spec.ts +65 -0
  55. package/src/shared/ids-stream.ts +47 -0
  56. package/src/shared/sse-schema.ts +5 -0
  57. package/src/shared/text-utils.spec.ts +42 -0
  58. package/src/shared/text-utils.ts +8 -0
package/dist/server.d.ts CHANGED
@@ -1823,6 +1823,13 @@ type DailyReportHandlersConfig = {
1823
1823
  streamKey: string;
1824
1824
  /** 未ログイン時のリダイレクト先 (index.loader 用、既定 "/auth/login")。 */
1825
1825
  loginRedirectPath?: string;
1826
+ /**
1827
+ * `intent=clearCache` (全サーバーキャッシュの一括破棄) を許可するか。既定 false。
1828
+ * 開発用アフォーダンスであり、有効化すると認証済みユーザーなら誰でも全ワーカーの
1829
+ * キャッシュを無制限に破棄できるため、本番では必ず無効のままにする
1830
+ * (消費アプリは開発環境でのみ true を注入する)。
1831
+ */
1832
+ enableDevCacheClear?: boolean;
1826
1833
  /** ロガー (既定は console ベース)。 */
1827
1834
  logger?: DailyReportLogger;
1828
1835
  };
@@ -1879,6 +1886,12 @@ type DailyReportServerConfig = Omit<DailyReportServiceConfig, "cache" | "epochs"
1879
1886
  attachmentConcurrency?: number;
1880
1887
  /** 未ログイン時のリダイレクト先 (index.loader 用、既定 "/auth/login")。 */
1881
1888
  loginRedirectPath?: string;
1889
+ /**
1890
+ * `intent=clearCache` (全サーバーキャッシュの一括破棄) を許可するか。既定 false。
1891
+ * 開発用アフォーダンス。有効化すると認証済みなら誰でも全ワーカーのキャッシュを
1892
+ * 無制限破棄できるため、本番では無効のままにする (消費アプリは開発環境のみ true 注入)。
1893
+ */
1894
+ enableDevCacheClear?: boolean;
1882
1895
  /** SQL 結果キャッシュの既定 TTL (既定 60,000ms)。 */
1883
1896
  cacheDefaultTtlMs?: number;
1884
1897
  /** 外部ソースアダプタ群 (レガシー日報テーブル等)。 */
package/dist/server.js CHANGED
@@ -1,12 +1,13 @@
1
- "use strict";var Le=Object.defineProperty;var Rt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var wt=Object.prototype.hasOwnProperty;var St=(t,e)=>{for(var s in e)Le(t,s,{get:e[s],enumerable:!0})},It=(t,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let p of Dt(e))!wt.call(t,p)&&p!==s&&Le(t,p,{get:()=>e[p],enumerable:!(i=Rt(e,p))||i.enumerable});return t};var At=t=>It(Le({},"__esModule",{value:!0}),t);var nr={};St(nr,{DailyReportSseReader:()=>De,SqlResultCache:()=>Re,asciiFallbackFileName:()=>st,createDailyReportHandlers:()=>ze,createDailyReportServer:()=>rr,createDailyReportService:()=>Ke,createEpochStore:()=>$e,defineDailyReportAuthzResources:()=>ot,defineDailyReportSchema:()=>tr,encodeRfc8187:()=>at,generateETag:()=>ke,isStreamIdLte:()=>we,jsonResponseWithETag:()=>ae,sanitizeMediaType:()=>Fe,seedDailyReportAuthzResources:()=>Vt,transformJsonArray:()=>er});module.exports=At(nr);var $e=t=>({async getEpoch(e){try{let s=await t?.getClient();if(!s)return 0;let i=await s.get(e);return i?Number(i):0}catch{return 0}},async incrementEpoch(e){try{let s=await t?.getClient();if(!s)return;await s.incr(e)}catch{}}}),Re=class{constructor(e,s){this.config=e;this.epochStore=s;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.getOrFetch=async e=>{let{cacheKey:s,forceRefresh:i,snapshot:p}=e,m=this.buckets.get(s);if(i&&(this.buckets.delete(s),this.inFlight.delete(s)),!i&&m&&m.expireAt>Date.now())if(e.epochKey){let y=await this.epochStore.getEpoch(e.epochKey);if(m.epoch===y)return p?m.records.map($=>structuredClone($)):m.records;this.buckets.delete(s)}else return p?m.records.map(y=>structuredClone(y)):m.records;if(!i&&this.inFlight.has(s)){let y=await this.inFlight.get(s);return p?y.map($=>structuredClone($)):y}let v;v=(async()=>{let y=await e.fetcher();if(i||this.inFlight.get(s)===v){let $=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs),d=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0;this.buckets.set(s,{records:y,expireAt:$,epoch:d}),this.buckets.size>500&&this.cleanExpired()}return y})(),i||this.inFlight.set(s,v);try{let y=await v;return p?y.map($=>structuredClone($)):y}finally{this.inFlight.delete(s)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let s of this.buckets.keys())s.startsWith(e)&&this.buckets.delete(s);for(let s of this.inFlight.keys())s.startsWith(e)&&this.inFlight.delete(s)}}cleanExpired(){let e=Date.now();for(let[s,i]of this.buckets.entries())i.expireAt<=e&&this.buckets.delete(s)}};var _t=/^\d{4}-\d{2}-\d{2}$/,Ct=/^\d{4}\/\d{2}\/\d{2}$/,Ge=t=>t<10?`0${t}`:`${t}`,Qe=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),s=Ge(t.getMonth()+1),i=Ge(t.getDate());return`${e}-${s}-${i}`},Z=t=>{if(t==null)return null;if(t instanceof Date)return Qe(t);let e=t.trim();if(e==="")return null;if(_t.test(e))return e;if(Ct.test(e))return e.replaceAll("/","-");let s=new Date(e);return Qe(s)};var Tt=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId,Xe=(t,e)=>{let s=t.findIndex(i=>Tt({businessDate:i.businessDate,reportHubId:i.reportHubId},e)>0);return s===-1?t.length:s};var ne=(t,e,s=console)=>{let i=p=>typeof p=="string"?[`${e} ${p}`]:[e,p];return{debug:(p,...m)=>{t<=0&&s.debug(...i(p),...m)},info:(p,...m)=>{t<=1&&s.info(...i(p),...m)},warn:(p,...m)=>{t<=2&&s.warn(...i(p),...m)},error:(p,...m)=>{t<=3&&s.error(...i(p),...m)}}};var u=require("zod"),Mt=u.z.object({name:u.z.string().nullish(),affiliation:u.z.string().nullish()}),kt=u.z.object({name:u.z.string().nullish(),text:u.z.string().nullish(),color:u.z.string().nullish()}),Et=u.z.object({id:u.z.number(),name:u.z.string().nullish(),color:u.z.string().nullish()}),We=u.z.object({id:u.z.number(),userId:u.z.string().nullish(),userName:u.z.string().nullish(),content:u.z.string().nullish(),createdAt:u.z.string().nullish(),isMine:u.z.boolean()}),xt=u.z.object({id:u.z.string(),fileName:u.z.string(),fileType:u.z.string().nullable(),fileSize:u.z.number().nullable(),createdAt:u.z.string().nullable(),state:u.z.enum(["present","absent","unknown"])}),Pe=u.z.object({reportHubId:u.z.number(),date:u.z.string().nullish(),createdAt:u.z.string().nullish(),author:u.z.string().nullish(),userId:u.z.string().nullish(),sourceType:u.z.string().nullish(),employeeName:u.z.string().nullish(),updatedBy:u.z.string().nullish(),updatedAt:u.z.string().nullish(),category:u.z.string().nullish(),creationCategory:u.z.string().nullish(),visitTimeFrom:u.z.string().nullish(),visitTimeTo:u.z.string().nullish(),customerName:u.z.string().nullish(),interviewers:u.z.array(Mt),subject:u.z.string().nullish(),content:u.z.string().nullish(),comments:u.z.array(kt),isRead:u.z.boolean(),isStarred:u.z.boolean(),labels:u.z.array(Et),commentItems:u.z.array(We),attachments:u.z.array(xt).default([])}),vt=u.z.object({type:u.z.literal("connected")}),Me=u.z.object({type:u.z.literal("status-update"),reportHubId:u.z.number(),statusType:u.z.enum(["star","read"]),value:u.z.boolean(),clientTempId:u.z.string(),recipientRawUserId:u.z.number().optional()}),Be=u.z.object({type:u.z.literal("comment-add"),reportHubId:u.z.number(),comment:We,clientTempId:u.z.string()}),Ue=u.z.object({type:u.z.literal("comment-delete"),reportHubId:u.z.number(),commentId:u.z.number(),clientTempId:u.z.string()}),He=u.z.object({type:u.z.literal("report-create"),reportHubId:u.z.number(),report:Pe,clientTempId:u.z.string(),recipientRawUserId:u.z.number().optional()}),Ye=u.z.object({type:u.z.literal("report-update"),reportHubId:u.z.number(),report:Pe,clientTempId:u.z.string(),recipientRawUserId:u.z.number().optional()}),qe=u.z.object({type:u.z.literal("report-publish"),reportHubId:u.z.number(),report:Pe,clientTempId:u.z.string(),recipientRawUserId:u.z.number().optional()}),Oe=u.z.object({type:u.z.literal("report-delete"),reportHubId:u.z.number(),clientTempId:u.z.string()}),Ve=u.z.discriminatedUnion("type",[vt,Me,Be,Ue,He,Ye,qe,Oe]);var Ze=require("crypto"),ke=t=>{let e=JSON.stringify(t);return`"${(0,Ze.createHash)("sha256").update(e).digest("hex")}"`};var Nt=ne(1,"[Response]"),ae=(t,e,s,i=200,p=Nt)=>{let m=ke(s),v=t.headers.get("If-None-Match");p.info(`[jsonResponseWithETag] ETag: ${m}, If-None-Match: ${v}`);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:m});return e&&y.append("Set-Cookie",e),t.method==="GET"&&i===200&&v===m?new Response(null,{status:304,headers:y}):new Response(JSON.stringify(s),{status:i,headers:y})};var et=require("events");var we=(t,e)=>{let[s,i]=t.split("-").map(Number),[p,m]=e.split("-").map(Number);return s!==p?s<p:i<=m},De=class{constructor(e){this.config=e;this._emitter=new et.EventEmitter;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=e.logger??ne(1,"[SSE Reader]")}subscribe(e,s){return this._emitter.on("entry",e),s&&this._emitter.on("error",s),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),s&&this._emitter.removeListener("error",s),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="0-0"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitter.emit("error",e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitter.emit("error",new Error("Failed to create Redis client for SSE reader"));return}this._client.on("error",e=>{this._logger.error("Redis client error:",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 s of e)for(let i of s.messages){this._lastId=i.id;try{let p=i.message?.data?JSON.parse(i.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 v=p?.reportHubId;typeof v=="number"&&(this.config.cache.invalidate(`daily-report:detail:${v}`),this.config.cache.invalidatePrefix(`daily-report:detail:${v}:user:`))}}catch{}this._emitter.emit("entry",{id:i.id,message:i.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitter.emit("error",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!=="idle";)await new Promise(e=>setTimeout(e,50))}}};var U=(t,e)=>new Response(JSON.stringify(t),{status:e?.status??200,headers:{"Content-Type":"application/json"}}),xe=200,nt=4e3,Lt="stream interrupted by server error",$t=/^\d{4}-\d{2}-\d{2}$/,Pt=t=>{let e=t.searchParams.get("cursor_report_hub_id"),s=t.searchParams.get("cursor_business_date");if(e===null)return s===null?{cursor:null}:{invalid:!0};let i=Number.parseInt(e,10);return!Number.isSafeInteger(i)||String(i)!==e||i<=0?{invalid:!0}:s===null?{cursor:{businessDate:null,reportHubId:i}}:$t.test(s)?{cursor:{businessDate:s,reportHubId:i}}:{invalid:!0}};async function*tt(t,e,s=xe){let i=e?Xe(t,e):0,p=!0;for(;;){let m=t.slice(i,i+(p?s:nt));i+=m.length;let v=i>=t.length,y=m[m.length-1];if(yield{items:m,nextCursor:v||!y?null:{businessDate:y.businessDate,reportHubId:y.reportHubId},isLast:v,...p?{total:t.length}:{}},p=!1,v)return}}var rt=(t,e,s,i)=>{let p=new TextEncoder,m=!1,v=new ReadableStream({async pull($){if(m||s.signal.aborted){await e.return(void 0).catch(()=>{});try{$.close()}catch{}return}try{let{value:d,done:P}=await e.next();if(P){$.close();return}if(m||s.signal.aborted){await e.return(void 0).catch(()=>{});try{$.close()}catch{}return}$.enqueue(p.encode(`${JSON.stringify(d)}
2
- `))}catch(d){if(m||s.signal.aborted)return;i.error(`ids-stream emission failed: ${d instanceof Error?d.message:String(d)}`);try{$.enqueue(p.encode(`${JSON.stringify({error:Lt})}
3
- `)),$.close()}catch{}}},cancel(){m=!0,e.return(void 0).catch(()=>{})}}),y=new Headers({"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"private, no-cache, no-transform","X-Content-Type-Options":"nosniff"});return t&&y.append("Set-Cookie",t),new Response(v,{status:200,headers:y})},Bt=32*1024*1024,Ut=60,Ht=4,Yt=12e4,qt=1024,Ot=60,Ft=5,zt=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),Kt=/^[\x20-\x7E]+$/,Jt=/^[\w.+-]+\/[\w.+-]+/,Fe=t=>t&&Kt.test(t)&&Jt.test(t)?t:null,at=t=>encodeURIComponent(t).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),st=t=>t.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),jt=t=>{switch(t){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},Gt={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},Qt=t=>{let e=new Map;return(s,i)=>{let p=e.get(s);p&&e.delete(s);let m=p??{tokens:t,lastRefillMs:i},v=Math.max(0,i-m.lastRefillMs);v>0&&(m.tokens=Math.min(t,m.tokens+v*t/6e4),m.lastRefillMs=i);let y=m.tokens>=1;for(y&&(m.tokens-=1),e.set(s,m);e.size>qt;){let $=e.keys().next();if($.done)break;e.delete($.value)}return y}},Xt=t=>{let e=0;return{tryAcquire:()=>e>=t?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},Wt=(t,e,s)=>{let i=setTimeout(e,s);i.unref?.();let p=()=>{clearTimeout(i),e()},m=!1;return new ReadableStream({pull(v){if(m){v.close(),p();return}m=!0,v.enqueue(t)},cancel(){p()}})};function ze(t){let{authenticate:e,service:s,encodeUserId:i,redis:p,sseReader:m,streamKey:v}=t,y=t.loginRedirectPath??"/auth/login",$=t.logger??ne(3,"[DailyReportAPI]"),d=t.logger??ne(1,"[DailyReportSSE]"),P=t.logger??ne(1,"[DailyReportAttachment]"),h=t.attachmentMaxBytes??Bt,K=Qt(t.attachmentRateLimitPerMinute??Ut),J=Xt(t.attachmentConcurrency??Ht),Y=async({request:k})=>{let{user:B,cookie:E}=await e(k,{failureRedirect:y}),x=new Headers;E&&x.append("Set-Cookie",E);let R=null;B&&(R=await s.getUserIdByExternalId(B.id));let _=R?i(R):null;return{data:{user:B,userId:_},headers:x}},he={"business-date":async(k,B,E,x)=>{let R=Z(k.searchParams.get("businessDate")),_=k.searchParams.get("forceRefresh")==="true";if(!R)return ae(E,B,{error:{message:"Invalid business date"}},400);let N=await s.getDailyReportsByBusinessDateByExternalId(R,x.id,{forceRefresh:_});return ae(E,B,{businessDate:R,reports:N},200)},"ids-stream":async(k,B,E,x)=>{let R=Pt(k);if("invalid"in R)return ae(E,B,{error:{message:"Invalid cursor"}},400);let _=k.searchParams.get("forceRefresh")==="true",N=s.getDailyReportIdsByExternalId(x.id,{forceRefresh:_});if(N.catch(()=>{}),R.cursor)return rt(B,tt(await N,R.cursor),E,$);let T=s.getDailyReportIdsFirstPageByExternalId(x.id,xe);T.catch(()=>{});let D=(async function*(){let S=await Promise.race([N.then(b=>({kind:"full",items:b}),b=>({kind:"full-error",error:b})),T.then(b=>({kind:"page",items:b}),()=>({kind:"page-error"}))]),I=null,A=null;if(S.kind==="full")A=S.items;else if(S.kind==="page"||S.kind==="full-error"){let b=S.kind==="page"?S.items:await T;if(b.length<xe){yield{items:b,nextCursor:null,isLast:!0,total:b.length};return}let q=b[b.length-1];I={businessDate:q.businessDate,reportHubId:q.reportHubId},yield{items:b,nextCursor:I,isLast:!1}}A===null&&(A=await N),yield*tt(A,I,I?nt:xe)})();return rt(B,D,E,$)},report:async(k,B,E,x)=>{let R=k.searchParams.get("reportHubId"),_=k.searchParams.get("forceRefresh")==="true",N=R?Number.parseInt(R,10):NaN;if(!Number.isFinite(N)||N<=0)return ae(E,B,{error:{message:"Invalid reportHubId"}},400);let T=await s.getDailyReportDetailByIdByExternalId(N,x.id,{snapshot:!0,forceRefresh:_});return T?ae(E,B,{report:T},200):ae(E,B,{error:{message:"Report not found"}},404)}};return{index:{loader:Y},api:{loader:async({request:k,params:B})=>{let{user:E,cookie:x}=await e(k,{failureRedirect:null}),R=x??null;if(!E)return ae(k,R,{error:{message:"Unauthorized"}},401);if(k.method!=="GET")return ae(k,R,{error:{message:"Method not allowed"}},405);let _=B.endpoint??"",N=he[_];if(!N)return ae(k,R,{error:{message:"Unknown endpoint"}},404);let T=Date.now();try{let D=new URL(k.url);return await N(D,R,k,E)}catch(D){let S=Date.now()-T,I=D instanceof Error?D:new Error(String(D));return $.error(`500 endpoint=${_} elapsed=${S}ms name=${I.name} code=${"code"in I?I.code:"N/A"} message=${I.message}`),$.error("Stack:",I.stack),ae(k,R,{error:{message:"Internal Server Error"}},500)}},action:async({request:k,params:B})=>{let{user:E}=await e(k,{failureRedirect:null});if(!E)return U({error:"Unauthorized"},{status:401});if(B.endpoint!=="action")return U({error:"Unknown endpoint"},{status:404});let R=await s.getUserIdByExternalId(E.id);if(!R)return U({error:"User not found"},{status:404});let _=await k.formData(),N=_.get("intent"),T=_.get("reportHubId"),D=T?Number(T):NaN,S=_.get("businessDate"),I=Number(_.get("operationTimestamp")),A=_.get("clientTempId");if(N==="clearCache")return await s.clearCache(),U({status:"OK",intent:"clearCache"});if(!A)return U({error:"clientTempId required"},{status:400});if(N!=="create"&&(!D||Number.isNaN(D)))return U({error:"Invalid reportHubId"},{status:400});switch(N){case"create":{if(!S)return U({error:"businessDate required"},{status:400});let b=await s.createDailyReport(R,S,A);return U({status:"OK",intent:"create",report:b,reportHubId:String(b.reportHubId),clientTempId:A})}case"update":{let b=_.get("title"),q=_.get("content");try{return await s.updateDailyReport(D,R,{title:b,content:q},A),U({status:"OK",intent:"update",reportHubId:String(D),clientTempId:A})}catch(O){if(O instanceof Error){if(O.message==="Unauthorized")return U({error:"Unauthorized"},{status:403});if(O.message==="Not Found")return U({error:"Report not found"},{status:404})}throw O}}case"publish":try{let b=await s.publishDailyReport(D,R,A);return U({status:"OK",intent:"publish",reportHubId:String(D),clientTempId:A,report:b})}catch(b){if(b instanceof Error){if(b.message==="Unauthorized")return U({error:"Unauthorized"},{status:403});if(b.message==="Not Found")return U({error:"Report not found"},{status:404})}throw b}case"delete":try{return await s.deleteDailyReport(D,R,A),U({status:"OK",intent:"delete",reportHubId:String(D),clientTempId:A})}catch(b){if(b instanceof Error){if(b.message==="Unauthorized")return U({error:"Unauthorized"},{status:403});if(b.message==="Not Found")return U({error:"Report not found"},{status:404})}throw b}case"toggleStar":{let b=_.get("isStarred");if(b===null)return U({error:"isStarred required"},{status:400});let q=b==="true",O=await s.setStarStatus(R,D,S,q,A);return U({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:O.isStarred,isRead:O.isRead},operationTimestamp:I,reportHubId:String(D),clientTempId:A})}case"toggleRead":{let b=_.get("isRead");if(b===null)return U({error:"isRead required"},{status:400});let q=b==="true",O=await s.setReadStatus(R,D,S,q,A);return U({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:O.isStarred,isRead:O.isRead},operationTimestamp:I,reportHubId:String(D),clientTempId:A})}case"addComment":{let b=_.get("content");if(!b)return U({error:"Content required"},{status:400});let q=await s.addComment(R,D,b,S,A),O={...q,userId:q.userId};return U({status:"OK",intent:"addComment",newComment:O,reportHubId:String(D),clientTempId:A})}case"deleteComment":{let b=Number(_.get("commentId"));if(!b||Number.isNaN(b))return U({error:"Invalid commentId"},{status:400});try{return await s.deleteComment(R,D,b,S,A),U({status:"OK",reportHubId:String(D),deletedCommentId:String(b),clientTempId:A})}catch(q){if(q instanceof Error){if(q.message==="Unauthorized")return U({error:"Unauthorized"},{status:403});if(q.message==="Not Found")return U({error:"Comment not found"},{status:404})}throw q}}default:return U({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:k,params:B})=>{let{user:E}=await e(k,{failureRedirect:null});if(!E)return new Response("Unauthorized",{status:401});let x=await s.getUserIdByExternalId(E.id);if(!x)return new Response("Forbidden",{status:403});if(B.endpoint!=="updates")return new Response("Not Found",{status:404});let _=new URL(k.url).searchParams.get("lastEventId")||k.headers.get("Last-Event-ID"),N=new TextEncoder,T=null,D=null,S=null,I=!1,A=()=>{if(!I){if(I=!0,D&&(clearInterval(D),D=null),S&&(S(),S=null),T)try{T.desiredSize!==null&&T.close()}catch{}finally{T=null}I=!1}},b=(O,G)=>{if(G.data)try{let C=JSON.parse(G.data),X=Ve.safeParse(C);if(!X.success){d.error("SSE message validation failed:",X.error.format());return}let te=X.data,se=typeof C.recipientRawUserId=="number"?C.recipientRawUserId:void 0;if(te.type==="status-update"){if(se===void 0||se!==x)return}else if(se!==void 0&&se!==x)return;let re;if("recipientRawUserId"in C){let{recipientRawUserId:ge,...pe}=C;re=JSON.stringify(pe)}else re=G.data;T&&T.desiredSize!==null&&T.enqueue(N.encode(`id: ${O}
1
+ "use strict";var Le=Object.defineProperty;var wt=Object.getOwnPropertyDescriptor;var It=Object.getOwnPropertyNames;var St=Object.prototype.hasOwnProperty;var At=(t,e)=>{for(var s in e)Le(t,s,{get:e[s],enumerable:!0})},Ct=(t,e,s,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let y of It(e))!St.call(t,y)&&y!==s&&Le(t,y,{get:()=>e[y],enumerable:!(i=wt(e,y))||i.enumerable});return t};var _t=t=>Ct(Le({},"__esModule",{value:!0}),t);var or={};At(or,{DailyReportSseReader:()=>De,SqlResultCache:()=>Re,asciiFallbackFileName:()=>it,createDailyReportHandlers:()=>ze,createDailyReportServer:()=>sr,createDailyReportService:()=>Ke,createEpochStore:()=>$e,defineDailyReportAuthzResources:()=>lt,defineDailyReportSchema:()=>ar,encodeRfc8187:()=>ot,generateETag:()=>Ee,isStreamIdLte:()=>we,jsonResponseWithETag:()=>ae,sanitizeMediaType:()=>Fe,seedDailyReportAuthzResources:()=>tr,transformJsonArray:()=>nr});module.exports=_t(or);var $e=t=>({async getEpoch(e){try{let s=await t?.getClient();if(!s)return 0;let i=await s.get(e);return i?Number(i):0}catch{return 0}},async incrementEpoch(e){try{let s=await t?.getClient();if(!s)return;await s.incr(e)}catch{}}}),Re=class{constructor(e,s){this.config=e;this.epochStore=s;this.buckets=new Map;this.inFlight=new Map;this.invalidate=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.getOrFetch=async e=>{let{cacheKey:s,forceRefresh:i,snapshot:y}=e,m=this.buckets.get(s);if(i&&(this.buckets.delete(s),this.inFlight.delete(s)),!i&&m&&m.expireAt>Date.now())if(e.epochKey){let h=await this.epochStore.getEpoch(e.epochKey);if(m.epoch===h)return y?m.records.map(O=>structuredClone(O)):m.records;this.buckets.delete(s)}else return y?m.records.map(h=>structuredClone(h)):m.records;if(!i&&this.inFlight.has(s)){let h=await this.inFlight.get(s);return y?h.map(O=>structuredClone(O)):h}let M;M=(async()=>{let h=await e.fetcher();if(i||this.inFlight.get(s)===M){let O=Date.now()+(e.ttlMsOverride??this.config.defaultTtlMs),u=e.epochKey?await this.epochStore.getEpoch(e.epochKey):0;this.buckets.set(s,{records:h,expireAt:O,epoch:u}),this.buckets.size>500&&this.cleanExpired()}return h})(),i||this.inFlight.set(s,M);try{let h=await M;return y?h.map(O=>structuredClone(O)):h}finally{this.inFlight.delete(s)}};this.flush=e=>{this.buckets.delete(e),this.inFlight.delete(e)};this.clearAll=()=>{this.buckets.clear(),this.inFlight.clear()};this.invalidatePrefix=e=>{for(let s of this.buckets.keys())s.startsWith(e)&&this.buckets.delete(s);for(let s of this.inFlight.keys())s.startsWith(e)&&this.inFlight.delete(s)}}cleanExpired(){let e=Date.now();for(let[s,i]of this.buckets.entries())i.expireAt<=e&&this.buckets.delete(s)}};var Tt=/^\d{4}-\d{2}-\d{2}$/,Mt=/^\d{4}\/\d{2}\/\d{2}$/,Qe=t=>t<10?`0${t}`:`${t}`,Xe=t=>{if(Number.isNaN(t.getTime()))return null;let e=t.getFullYear(),s=Qe(t.getMonth()+1),i=Qe(t.getDate());return`${e}-${s}-${i}`};var ee=t=>{if(t==null)return null;if(t instanceof Date)return Xe(t);let e=t.trim();if(e==="")return null;if(Tt.test(e))return e;if(Mt.test(e))return e.replaceAll("/","-");let s=new Date(e);return Xe(s)};var Et=(t,e)=>t.businessDate!==e.businessDate?t.businessDate===null?1:e.businessDate===null||t.businessDate>e.businessDate?-1:1:e.reportHubId-t.reportHubId;var We=(t,e)=>{let s=t.findIndex(i=>Et({businessDate:i.businessDate,reportHubId:i.reportHubId},e)>0);return s===-1?t.length:s};var ne=(t,e,s=console)=>{let i=y=>typeof y=="string"?[`${e} ${y}`]:[e,y];return{debug:(y,...m)=>{t<=0&&s.debug(...i(y),...m)},info:(y,...m)=>{t<=1&&s.info(...i(y),...m)},warn:(y,...m)=>{t<=2&&s.warn(...i(y),...m)},error:(y,...m)=>{t<=3&&s.error(...i(y),...m)}}};var d=require("zod"),kt=d.z.object({name:d.z.string().nullish(),affiliation:d.z.string().nullish()}),vt=d.z.object({name:d.z.string().nullish(),text:d.z.string().nullish(),color:d.z.string().nullish()}),xt=d.z.object({id:d.z.number(),name:d.z.string().nullish(),color:d.z.string().nullish()}),Ve=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()}),Nt=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"])}),Pe=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(kt),subject:d.z.string().nullish(),content:d.z.string().nullish(),comments:d.z.array(vt),isRead:d.z.boolean(),isStarred:d.z.boolean(),labels:d.z.array(xt),commentItems:d.z.array(Ve),attachments:d.z.array(Nt).default([])}),Lt=d.z.object({type:d.z.literal("connected")}),Me=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()}),Be=d.z.object({type:d.z.literal("comment-add"),reportHubId:d.z.number(),comment:Ve,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),Ue=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()}),He=d.z.object({type:d.z.literal("report-create"),reportHubId:d.z.number(),report:Pe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),Ye=d.z.object({type:d.z.literal("report-update"),reportHubId:d.z.number(),report:Pe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),Oe=d.z.object({type:d.z.literal("report-publish"),reportHubId:d.z.number(),report:Pe,clientTempId:d.z.string(),recipientRawUserId:d.z.number().optional()}),qe=d.z.object({type:d.z.literal("report-delete"),reportHubId:d.z.number(),clientTempId:d.z.string()}),Ze=d.z.discriminatedUnion("type",[Lt,Me,Be,Ue,He,Ye,Oe,qe]);var et=require("crypto"),Ee=t=>{let e=JSON.stringify(t);return`"${(0,et.createHash)("sha256").update(e).digest("hex")}"`};var $t=ne(1,"[Response]"),ae=(t,e,s,i=200,y=$t)=>{let m=Ee(s),M=t.headers.get("If-None-Match");y.info(`[jsonResponseWithETag] ETag: ${m}, If-None-Match: ${M}`);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"&&i===200&&M===m?new Response(null,{status:304,headers:h}):new Response(JSON.stringify(s),{status:i,headers:h})};var tt=require("events");var we=(t,e)=>{let[s,i]=t.split("-").map(Number),[y,m]=e.split("-").map(Number);return s!==y?s<y:i<=m},De=class{constructor(e){this.config=e;this._emitter=new tt.EventEmitter;this._state="idle";this._refCount=0;this._lastId="0-0";this._emitter.setMaxListeners(0),this._logger=e.logger??ne(1,"[SSE Reader]")}subscribe(e,s){return this._emitter.on("entry",e),s&&this._emitter.on("error",s),this._refCount++,this._refCount===1&&this._startLoop(),()=>{this._emitter.removeListener("entry",e),s&&this._emitter.removeListener("error",s),this._refCount--,this._refCount<=0&&(this._refCount=0,this._stopLoop())}}async destroy(){this._refCount=0,await this._stopLoop(),this._emitter.removeAllListeners(),this._lastId="0-0"}async _startLoop(){for(;this._state==="stopping";)await new Promise(e=>setTimeout(e,50));if(this._state!=="running"){this._state="running";try{this._client=await this.config.redis?.createClient()}catch(e){this._state="idle",this._emitter.emit("error",e instanceof Error?e:new Error("Failed to create Redis client for SSE reader"));return}if(!this._client){this._state="idle",this._emitter.emit("error",new Error("Failed to create Redis client for SSE reader"));return}this._client.on("error",e=>{this._logger.error("Redis client error:",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 s of e)for(let i of s.messages){this._lastId=i.id;try{let y=i.message?.data?JSON.parse(i.message.data):null,m=y?.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 M=y?.reportHubId;typeof M=="number"&&(this.config.cache.invalidate(`daily-report:detail:${M}`),this.config.cache.invalidatePrefix(`daily-report:detail:${M}:user:`))}}catch{}this._emitter.emit("entry",{id:i.id,message:i.message})}}}catch(e){!(e?.constructor?.name==="ClientClosedError")&&this._state==="running"&&(this._logger.error("xRead loop error:",e),this._emitter.emit("error",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!=="idle";)await new Promise(e=>setTimeout(e,50))}}};var L=(t,e)=>new Response(JSON.stringify(t),{status:e?.status??200,headers:{"Content-Type":"application/json"}}),ve=200,st=4e3,Pt="stream interrupted by server error",Bt=/^\d{4}-\d{2}-\d{2}$/,Ut=15e3,rt=Symbol("ids-stream-heartbeat"),Ht=t=>{let e=t.searchParams.get("cursor_report_hub_id"),s=t.searchParams.get("cursor_business_date");if(e===null)return s===null?{cursor:null}:{invalid:!0};let i=Number.parseInt(e,10);return!Number.isSafeInteger(i)||String(i)!==e||i<=0?{invalid:!0}:s===null?{cursor:{businessDate:null,reportHubId:i}}:Bt.test(s)?{cursor:{businessDate:s,reportHubId:i}}:{invalid:!0}};async function*nt(t,e,s=ve){let i=e?We(t,e):0,y=!0;for(;;){let m=t.slice(i,i+(y?s:st));i+=m.length;let M=i>=t.length,h=m[m.length-1];if(yield{items:m,nextCursor:M||!h?null:{businessDate:h.businessDate,reportHubId:h.reportHubId},isLast:M,...y?{total:t.length}:{}},y=!1,M)return}}var at=(t,e,s,i)=>{let y=new TextEncoder,m=!1,M=null,h=new ReadableStream({async pull(u){if(m||s.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}let N=null;try{M===null&&(M=e.next());let p=new Promise(me=>{N=setTimeout(()=>me(rt),Ut)}),K=await Promise.race([M,p]);if(N!==null&&(clearTimeout(N),N=null),K===rt){if(m||s.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(y.encode(`
2
+ `));return}M=null;let{value:q,done:U}=K;if(U){u.close();return}if(m||s.signal.aborted){await e.return(void 0).catch(()=>{});try{u.close()}catch{}return}u.enqueue(y.encode(`${JSON.stringify(q)}
3
+ `))}catch(p){if(N!==null&&clearTimeout(N),M=null,m||s.signal.aborted)return;i.error(`ids-stream emission failed: ${p instanceof Error?p.message:String(p)}`);try{u.enqueue(y.encode(`${JSON.stringify({error:Pt})}
4
+ `)),u.close()}catch{}}},cancel(){m=!0,e.return(void 0).catch(()=>{})}}),O=new Headers({"Content-Type":"application/x-ndjson; charset=utf-8","Cache-Control":"private, no-cache, no-transform","X-Content-Type-Options":"nosniff"});return t&&O.append("Set-Cookie",t),new Response(h,{status:200,headers:O})},Yt=32*1024*1024,Ot=60,qt=4,Ft=12e4,zt=1024,Kt=60,Jt=5,jt=new Set(["image/png","image/jpeg","image/gif","image/webp","application/pdf","text/plain"]),Gt=/^[\x20-\x7E]+$/,Qt=/^[\w.+-]+\/[\w.+-]+/,Fe=t=>t&&Gt.test(t)&&Qt.test(t)?t:null,ot=t=>encodeURIComponent(t).replace(/['()*]/g,e=>`%${e.charCodeAt(0).toString(16).toUpperCase()}`),it=t=>t.replace(/[^\x20-\x7E]/g,"_").replace(/["\\]/g,"_"),Xt=t=>{switch(t){case"not_found":case"denied":case"invalid_path":return 404;case"too_large":return 413;default:return 502}},Wt={404:"Attachment not found",413:"Attachment too large",502:"Attachment storage unavailable"},Vt=t=>{let e=new Map;return(s,i)=>{let y=e.get(s);y&&e.delete(s);let m=y??{tokens:t,lastRefillMs:i},M=Math.max(0,i-m.lastRefillMs);M>0&&(m.tokens=Math.min(t,m.tokens+M*t/6e4),m.lastRefillMs=i);let h=m.tokens>=1;for(h&&(m.tokens-=1),e.set(s,m);e.size>zt;){let O=e.keys().next();if(O.done)break;e.delete(O.value)}return h}},Zt=t=>{let e=0;return{tryAcquire:()=>e>=t?!1:(e+=1,!0),release:()=>{e>0&&(e-=1)}}},er=(t,e,s)=>{let i=setTimeout(e,s);i.unref?.();let y=()=>{clearTimeout(i),e()},m=!1;return new ReadableStream({pull(M){if(m){M.close(),y();return}m=!0,M.enqueue(t)},cancel(){y()}})};function ze(t){let{authenticate:e,service:s,encodeUserId:i,redis:y,sseReader:m,streamKey:M}=t,h=t.loginRedirectPath??"/auth/login",O=t.logger??ne(3,"[DailyReportAPI]"),u=t.logger??ne(1,"[DailyReportSSE]"),N=t.logger??ne(1,"[DailyReportAttachment]"),p=t.attachmentMaxBytes??Yt,K=Vt(t.attachmentRateLimitPerMinute??Ot),q=Zt(t.attachmentConcurrency??qt),U=async({request:k})=>{let{user:H,cookie:v}=await e(k,{failureRedirect:h}),x=new Headers;v&&x.append("Set-Cookie",v);let R=null;H&&(R=await s.getUserIdByExternalId(H.id));let C=R?i(R):null;return{data:{user:H,userId:C},headers:x}},me={"business-date":async(k,H,v,x)=>{let R=ee(k.searchParams.get("businessDate")),C=k.searchParams.get("forceRefresh")==="true";if(!R)return ae(v,H,{error:{message:"Invalid business date"}},400);let $=await s.getDailyReportsByBusinessDateByExternalId(R,x.id,{forceRefresh:C});return ae(v,H,{businessDate:R,reports:$},200)},"ids-stream":async(k,H,v,x)=>{let R=Ht(k);if("invalid"in R)return ae(v,H,{error:{message:"Invalid cursor"}},400);let C=k.searchParams.get("forceRefresh")==="true",$=s.getDailyReportIdsByExternalId(x.id,{forceRefresh:C});if($.catch(()=>{}),R.cursor)return at(H,nt(await $,R.cursor),v,O);let E=s.getDailyReportIdsFirstPageByExternalId(x.id,ve);E.catch(()=>{});let D=(async function*(){let w=await Promise.race([$.then(g=>({kind:"full",items:g}),g=>({kind:"full-error",error:g})),E.then(g=>({kind:"page",items:g}),()=>({kind:"page-error"}))]),I=null,_=null;if(w.kind==="full")_=w.items;else if(w.kind==="page"||w.kind==="full-error"){let g=w.kind==="page"?w.items:await E;if(g.length<ve){yield{items:g,nextCursor:null,isLast:!0,total:g.length};return}let P=g[g.length-1];I={businessDate:P.businessDate,reportHubId:P.reportHubId},yield{items:g,nextCursor:I,isLast:!1}}_===null&&(_=await $),yield*nt(_,I,I?st:ve)})();return at(H,D,v,O)},report:async(k,H,v,x)=>{let R=k.searchParams.get("reportHubId"),C=k.searchParams.get("forceRefresh")==="true",$=R?Number.parseInt(R,10):NaN;if(!Number.isFinite($)||$<=0)return ae(v,H,{error:{message:"Invalid reportHubId"}},400);let E=await s.getDailyReportDetailByIdByExternalId($,x.id,{snapshot:!0,forceRefresh:C});return E?ae(v,H,{report:E},200):ae(v,H,{error:{message:"Report not found"}},404)}};return{index:{loader:U},api:{loader:async({request:k,params:H})=>{let{user:v,cookie:x}=await e(k,{failureRedirect:null}),R=x??null;if(!v)return ae(k,R,{error:{message:"Unauthorized"}},401);if(k.method!=="GET")return ae(k,R,{error:{message:"Method not allowed"}},405);let C=H.endpoint??"",$=me[C];if(!$)return ae(k,R,{error:{message:"Unknown endpoint"}},404);let E=Date.now();try{let D=new URL(k.url);return await $(D,R,k,v)}catch(D){let w=Date.now()-E,I=D instanceof Error?D:new Error(String(D));return O.error(`500 endpoint=${C} elapsed=${w}ms name=${I.name} code=${"code"in I?I.code:"N/A"} message=${I.message}`),O.error("Stack:",I.stack),ae(k,R,{error:{message:"Internal Server Error"}},500)}},action:async({request:k,params:H})=>{let{user:v}=await e(k,{failureRedirect:null});if(!v)return L({error:"Unauthorized"},{status:401});if(H.endpoint!=="action")return L({error:"Unknown endpoint"},{status:404});let R=await s.getUserIdByExternalId(v.id);if(!R)return L({error:"User not found"},{status:404});let C=await k.formData(),$=C.get("intent"),E=C.get("reportHubId"),D=E?Number(E):NaN,w=C.get("businessDate"),I=Number(C.get("operationTimestamp")),_=C.get("clientTempId");if($==="clearCache")return t.enableDevCacheClear?(await s.clearCache(),L({status:"OK",intent:"clearCache"})):L({error:"Invalid intent"},{status:400});if(!_)return L({error:"clientTempId required"},{status:400});if($!=="create"&&(!D||Number.isNaN(D)))return L({error:"Invalid reportHubId"},{status:400});switch($){case"create":{if(!w)return L({error:"businessDate required"},{status:400});let g=await s.createDailyReport(R,w,_);return L({status:"OK",intent:"create",report:g,reportHubId:String(g.reportHubId),clientTempId:_})}case"update":{let g=C.get("title"),P=C.get("content");try{return await s.updateDailyReport(D,R,{title:g,content:P},_),L({status:"OK",intent:"update",reportHubId:String(D),clientTempId:_})}catch(F){if(F instanceof Error){if(F.message==="Unauthorized")return L({error:"Unauthorized"},{status:403});if(F.message==="Not Found")return L({error:"Report not found"},{status:404})}throw F}}case"publish":try{let g=await s.publishDailyReport(D,R,_);return L({status:"OK",intent:"publish",reportHubId:String(D),clientTempId:_,report:g})}catch(g){if(g instanceof Error){if(g.message==="Unauthorized")return L({error:"Unauthorized"},{status:403});if(g.message==="Not Found")return L({error:"Report not found"},{status:404})}throw g}case"delete":try{return await s.deleteDailyReport(D,R,_),L({status:"OK",intent:"delete",reportHubId:String(D),clientTempId:_})}catch(g){if(g instanceof Error){if(g.message==="Unauthorized")return L({error:"Unauthorized"},{status:403});if(g.message==="Not Found")return L({error:"Report not found"},{status:404})}throw g}case"toggleStar":{let g=C.get("isStarred");if(g===null)return L({error:"isStarred required"},{status:400});let P=g==="true",F=await s.setStarStatus(R,D,w,P,_);return L({status:"OK",intent:"toggleStar",updatedStatus:{isStarred:F.isStarred,isRead:F.isRead},operationTimestamp:I,reportHubId:String(D),clientTempId:_})}case"toggleRead":{let g=C.get("isRead");if(g===null)return L({error:"isRead required"},{status:400});let P=g==="true",F=await s.setReadStatus(R,D,w,P,_);return L({status:"OK",intent:"toggleRead",updatedStatus:{isStarred:F.isStarred,isRead:F.isRead},operationTimestamp:I,reportHubId:String(D),clientTempId:_})}case"addComment":{let g=C.get("content");if(!g)return L({error:"Content required"},{status:400});try{let P=await s.addComment(R,D,g,w,_),F={...P,userId:P.userId};return L({status:"OK",intent:"addComment",newComment:F,reportHubId:String(D),clientTempId:_})}catch(P){if(P instanceof Error){if(P.message==="Not Found")return L({error:"Report not found"},{status:404});if(P.message.startsWith("Comments are restricted"))return L({error:"Comments are restricted for this report"},{status:403})}throw P}}case"deleteComment":{let g=Number(C.get("commentId"));if(!g||Number.isNaN(g))return L({error:"Invalid commentId"},{status:400});try{return await s.deleteComment(R,D,g,w,_),L({status:"OK",reportHubId:String(D),deletedCommentId:String(g),clientTempId:_})}catch(P){if(P instanceof Error){if(P.message==="Unauthorized")return L({error:"Unauthorized"},{status:403});if(P.message==="Not Found")return L({error:"Comment not found"},{status:404})}throw P}}default:return L({error:"Invalid intent"},{status:400})}}},sse:{loader:async({request:k,params:H})=>{let{user:v}=await e(k,{failureRedirect:null});if(!v)return new Response("Unauthorized",{status:401});let x=await s.getUserIdByExternalId(v.id);if(!x)return new Response("Forbidden",{status:403});if(H.endpoint!=="updates")return new Response("Not Found",{status:404});let C=new URL(k.url).searchParams.get("lastEventId")||k.headers.get("Last-Event-ID"),$=new TextEncoder,E=null,D=null,w=null,I=!1,_=()=>{if(!I){if(I=!0,D&&(clearInterval(D),D=null),w&&(w(),w=null),E)try{E.desiredSize!==null&&E.close()}catch{}finally{E=null}I=!1}},g=(F,G)=>{if(G.data)try{let T=JSON.parse(G.data),W=Ze.safeParse(T);if(!W.success){u.error("SSE message validation failed:",W.error.format());return}let te=W.data,se=typeof T.recipientRawUserId=="number"?T.recipientRawUserId:void 0;if(te.type==="status-update"){if(se===void 0||se!==x)return}else if(se!==void 0&&se!==x)return;let re;if("recipientRawUserId"in T){let{recipientRawUserId:be,...ye}=T;re=JSON.stringify(ye)}else re=G.data;E&&E.desiredSize!==null&&E.enqueue($.encode(`id: ${F}
4
5
  data: ${re}
5
6
 
6
- `))}catch(C){d.error(`[SSE:${x}] processEntry error:`,C)}},q=new ReadableStream({async start(O){T=O,D=setInterval(()=>{try{T&&T.desiredSize!==null?T.enqueue(N.encode(`: keep-alive
7
+ `))}catch(T){u.error(`[SSE:${x}] processEntry error:`,T)}},P=new ReadableStream({async start(F){E=F,D=setInterval(()=>{try{E&&E.desiredSize!==null?E.enqueue($.encode(`: keep-alive
7
8
 
8
- `)):A()}catch{A()}},5e3),k.signal.addEventListener("abort",()=>{A()});let G=_||"0-0";if(S=m.subscribe(C=>{we(C.id,G)||(G=C.id,b(C.id,C.message))},C=>{d.error(`[SSE:${x}] Fan-Out reader error:`,C),A()}),!_)try{let C=await p?.getClient();if(C){let X=await C.xRevRange(v,"+","-",{COUNT:1});X.length>0&&!we(X[0].id,G)&&(G=X[0].id)}}catch{}if(T&&T.desiredSize!==null){let C=`data: ${JSON.stringify({type:"connected"})}
9
+ `)):_()}catch{_()}},5e3),k.signal.addEventListener("abort",()=>{_()});let G=C||"0-0";if(w=m.subscribe(T=>{we(T.id,G)||(G=T.id,g(T.id,T.message))},T=>{u.error(`[SSE:${x}] Fan-Out reader error:`,T),_()}),!C)try{let T=await y?.getClient();if(T){let W=await T.xRevRange(M,"+","-",{COUNT:1});W.length>0&&!we(W[0].id,G)&&(G=W[0].id)}}catch{}if(E&&E.desiredSize!==null){let T=`data: ${JSON.stringify({type:"connected"})}
9
10
 
10
- `,X=G!=="0-0"?`id: ${G}
11
- ${C}`:C;T.enqueue(N.encode(X))}if(_)try{let C=await p?.getClient();if(C){let X=await C.xRange(v,_,"+",{COUNT:1e3});for(let te of X)te.id!==_&&(we(te.id,G)||(G=te.id,b(te.id,te.message)))}}catch(C){d.error(`[SSE:${x}] catch-up xRange error:`,C)}},cancel(){A()}});return new Response(q,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}},attachment:{loader:async({request:k,params:B})=>{let E=null,x=(R,_,N)=>{let T=new Headers({"Content-Type":"application/json"});return N!==void 0&&T.set("Retry-After",String(N)),E&&T.append("Set-Cookie",E),new Response(JSON.stringify({error:{message:_}}),{status:R,headers:T})};try{let{user:R,cookie:_}=await e(k,{failureRedirect:null});if(E=_??null,!R)return x(401,"Unauthorized");if(k.method!=="GET"&&k.method!=="HEAD")return x(405,"Method not allowed");let N=t.attachmentIdCodec,T=t.readAttachment;if(!(N&&T))return x(404,"Attachment not found");let D=B.token??"",S=N.decode(D);if(S===null||!Number.isSafeInteger(S)||S<=0)return x(400,"Invalid attachment token");let I=await s.getUserIdByExternalId(R.id);if(!I)return x(403,"Forbidden");if(!K(I,Date.now()))return P.error(`429 attachment=${S} viewer=${I} reason=rate_limit`),x(429,"Too many requests",Ot);let A=await s.getAttachmentForUser(S,I);if(!A)return P.error(`404 attachment=${S} viewer=${I} reason=not_visible`),x(404,"Attachment not found");if(A.fileSize!=null&&A.fileSize>h)return P.error(`413 attachment=${S} viewer=${I} reason=db_size`),x(413,"Attachment too large");if(!J.tryAcquire())return P.error(`503 attachment=${S} viewer=${I} reason=concurrency`),x(503,"Too many concurrent downloads",Ft);let b=!1,q=()=>{b||(b=!0,J.release())},O=!1;try{let G=k.method==="HEAD",C=await T(A.filePath,{maxBytes:h,head:G,principal:i(I)});if(!C.ok){let oe=jt(C.reason);return C.reason==="not_found"&&s.markAttachmentMissing(S).catch(de=>{P.error(`markAttachmentMissing failed attachment=${S} message=${de instanceof Error?de.message:"unknown"}`)}),P.error(`${oe} attachment=${S} viewer=${I} reason=${C.reason} code=${C.code??"-"}`),x(oe,Gt[oe]??"Attachment storage unavailable")}let X=Fe(A.fileType)??Fe(C.contentType)??"application/octet-stream",te=zt.has(X),se=new URL(k.url).searchParams.get("download")==="1",re=te?X:"application/octet-stream",ge=te&&!se?"inline":"attachment",pe=C.size??C.bytes.byteLength,ie=new Headers({"Content-Type":re,"Content-Length":String(pe),"Content-Disposition":`${ge}; filename="${st(A.fileName)}"; filename*=UTF-8''${at(A.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return E&&ie.append("Set-Cookie",E),s.markAttachmentPresent(S).catch(oe=>{P.error(`markAttachmentPresent failed attachment=${S} message=${oe instanceof Error?oe.message:"unknown"}`)}),P.info(`200 attachment=${S} viewer=${I} type=${re} disposition=${ge} bytes=${pe}`),G?new Response(null,{status:200,headers:ie}):(O=!0,new Response(Wt(C.bytes,q,Yt),{status:200,headers:ie}))}finally{O||q()}}catch(R){if(R instanceof Response)throw R;return P.error(`500 attachment=? viewer=? reason=unexpected message=${R instanceof Error?R.message:"unknown"}`),x(500,"Attachment request failed")}}}}}var n=require("drizzle-orm");var me=t=>(0,n.getColumns)(t);function Ke(t){let{db:e,tables:s,userTable:i,resolveUserId:p,encodeUserId:m,redis:v,cache:y,epochs:$}=t,{hub:d,internal:P,comment:h,label:K,hubLabel:J,userStatus:Y}=s,he=t.externalSources??[],Ae=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],_e=Ae[0]??"\u4E0B\u66F8\u304D",W=t.logger??ne(1,"[DailyReportService]"),fe="daily-report:ids",k=t.idsTtlMs??18e4,B="daily-report:ids:epoch",E="daily-report:business-date:",x=t.businessDateTtlMs??3e5,R="daily-report:date-epoch:",_="daily-report:detail-epoch:",N=t.streamKey??"daily-report:sse-stream",T=t.streamMaxLen??1e4,D=r=>$.incrementEpoch(r),S=async(r,a)=>{let o=await v?.getClient();if(!o){W.warn(`[SSE] Redis client unavailable (${a})`);return}let c=Date.now();try{await o.xAdd(N,"*",{data:JSON.stringify(r)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:T}});let f=Date.now()-c;f>1e3&&W.warn(`[SSE] Slow publish (${a}): ${f}ms`)}catch(f){W.error(`[SSE] Redis publish failed (${a}):`,f)}},I=(r,a)=>{if(!r)return null;let o=r instanceof Date?r:new Date(r);if(Number.isNaN(o.getTime()))return typeof r=="string"?r:null;let c=a==="YYYY-MM-DD HH:mm:ss"?{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}:{year:"numeric",month:"2-digit",day:"2-digit"};return(a==="YYYY-MM-DD HH:mm:ss"?o.toLocaleString("ja-JP",c):o.toLocaleDateString("ja-JP",c)).replace(/\//g,"-")},A=r=>r==null||r===""?null:/^\d+$/.test(r)?m(Number(r)):r,b=()=>{let r={};for(let a of he)r[`ext_${a.sourceType}`]=me(a.table);return r},q=r=>{let a=r;for(let o of he)a=a.leftJoin(o.table,(0,n.and)((0,n.eq)(d.sourceType,o.sourceType),(0,n.eq)(d.sourceIdNum,o.idColumn)));return a},O=(r,a)=>{let{hub:o,internal:c}=r,f=o.summary,g=[],w=null,M=null,F=null,j=null,H=null,ee=null,le=[],ce=he.find(L=>L.sourceType===o.sourceType),ye=ce?r[`ext_${ce.sourceType}`]:void 0;if(ce&&ye){let L=ce.mapRow(ye);L.content!==void 0&&(f=L.content),L.employeeName!==void 0&&(ee=L.employeeName),L.category!==void 0&&(w=L.category),L.creationCategory!==void 0&&(M=L.creationCategory),L.visitTimeFrom!==void 0&&(F=L.visitTimeFrom),L.visitTimeTo!==void 0&&(j=L.visitTimeTo),L.customerName!==void 0&&(H=L.customerName),L.interviewers!==void 0&&(g=L.interviewers),L.comments!==void 0&&(le=L.comments)}else o.sourceType==="Internal"&&c&&(f=c.body);let ue=(r.labels??[]).map(L=>({id:L.id,name:L.name,color:L.color})),V=r.comments??[],z=M?Ae.includes(M):!1,Q=ie?.[0]??null;return z&&Q&&!ue.some(L=>L.id===Q)&&ue.push({id:Q,name:_e,color:null}),{reportHubId:o.id,date:I(o.businessDate,"YYYY-MM-DD"),author:r.creatorName??A(o.createdBy)??"",userId:o.userId?m(o.userId):"",sourceType:o.sourceType??"Internal",createdAt:I(o.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:I(o.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:A(o.updatedBy),employeeName:ee??r.creatorName??A(o.createdBy),category:w,creationCategory:M,visitTimeFrom:F,visitTimeTo:j,customerName:H,interviewers:g,subject:o.title,content:f,comments:le,isRead:r.isRead??!1,isStarred:r.isStarred??!1,labels:ue,commentItems:V.map(L=>({...L,userId:m(L.userId),isMine:a?L.userId===a:!1})),attachments:r.attachments}},G=async r=>{let a=(0,n.aliasedTable)(J,"draft_label"),o=await de();return(await e.select({reportHubId:d.id,businessDate:d.businessDate,sourceType:d.sourceType}).from(d).leftJoin(a,(0,n.and)((0,n.eq)(a.hubId,d.id),(0,n.inArray)(a.labelId,o))).where((0,n.and)((0,n.isNull)(d.deletedAt),(0,n.or)((0,n.eq)(d.userId,r),(0,n.isNull)(d.userId),(0,n.isNull)(a.hubId)))).orderBy((0,n.desc)(d.businessDate),(0,n.desc)(d.id))).map(f=>({...f,businessDate:I(f.businessDate,"YYYY-MM-DD")}))},C=async(r,a)=>{let o=await re(r);if(!o)return[];let c=(0,n.aliasedTable)(J,"draft_label"),f=await de();return(await e.select({reportHubId:d.id,businessDate:d.businessDate,sourceType:d.sourceType}).top(a).from(d).leftJoin(c,(0,n.and)((0,n.eq)(c.hubId,d.id),(0,n.inArray)(c.labelId,f))).where((0,n.and)((0,n.isNull)(d.deletedAt),(0,n.or)((0,n.eq)(d.userId,o),(0,n.isNull)(d.userId),(0,n.isNull)(c.hubId)))).orderBy((0,n.desc)(d.businessDate),(0,n.desc)(d.id))).map(w=>({...w,businessDate:I(w.businessDate,"YYYY-MM-DD")}))},X=async r=>{let a=await q(e.select({hub:me(d),internal:me(P),creatorName:i.displayName,...b()}).from(d)).leftJoin(P,(0,n.eq)(d.id,P.hubId)).leftJoin(i,(0,n.eq)(d.userId,i.id)).where((0,n.and)((0,n.eq)(d.businessDate,n.sql`${r}`),(0,n.isNull)(d.deletedAt))).orderBy((0,n.desc)(d.id)),o=await Ce(a.map(c=>c.hub.id));return a.map(c=>O({...c,attachments:o.get(c.hub.id)??[]}))},te=r=>`${E}${r}`,se=new Map,re=async r=>{if(!t.disableUserIdCache&&se.has(r))return se.get(r)??null;let a=await p(r);return a!==null&&!t.disableUserIdCache&&se.set(r,a),a},ge=async(r,{forceRefresh:a=!1,snapshot:o=!1,ttlMsOverride:c}={})=>{let f=await re(r);if(!f)return[];let g=`${fe}:user:${f}`;return y.getOrFetch({cacheKey:g,fetcher:async()=>await G(f),forceRefresh:a,snapshot:o,ttlMsOverride:c??k,epochKey:B})},pe=(r,{forceRefresh:a=!1,snapshot:o=!1,ttlMsOverride:c}={})=>{let f=Z(r);return f?y.getOrFetch({cacheKey:te(f),fetcher:()=>X(f),forceRefresh:a,snapshot:o,ttlMsOverride:c??x}):Promise.resolve([])},ie=null,oe=async()=>(ie!==null||(ie=(await e.select({id:K.id}).from(K).where((0,n.inArray)(K.name,Ae)).orderBy(K.id)).map(a=>a.id)),ie),de=async()=>{let r=await oe();return r.length>0?r:[-1]},ve=async()=>{let r=await oe();if(r.length===0)return null;let[a]=await e.select({id:K.id}).top(1).from(K).where((0,n.eq)(K.name,_e));return a?.id??r[0]},it=(r,a)=>a!=null?"absent":r!=null?"present":"unknown",Ce=async r=>{let a=new Map,o=s.attachment,c=t.attachmentIdCodec;if(r.length===0||!o||!c)return a;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,n.inArray)(o.hubId,r)).orderBy((0,n.asc)(o.createdAt),(0,n.asc)(o.id));for(let g of f){let w={id:c.encode(Number(g.id)),fileName:String(g.fileName),fileType:g.fileType?String(g.fileType):null,fileSize:g.fileSize!=null?Number(g.fileSize):null,createdAt:I(g.createdAt,"YYYY-MM-DD HH:mm:ss"),state:it(g.objectCheckedAt,g.objectMissingAt)},M=a.get(Number(g.hubId));M?M.push(w):a.set(Number(g.hubId),[w])}return a},lt=async(r,a)=>{let o=s.attachment;if(!o)return null;let c=await de(),f=(0,n.aliasedTable)(J,"draft_label");return(await e.select({fileName:o.fileName,filePath:o.filePath,fileType:o.fileType,fileSize:o.fileSize}).top(1).from(o).innerJoin(d,(0,n.eq)(d.id,o.hubId)).leftJoin(f,(0,n.and)((0,n.eq)(f.hubId,d.id),(0,n.inArray)(f.labelId,c))).where((0,n.and)((0,n.eq)(o.id,r),(0,n.isNull)(d.deletedAt),(0,n.or)((0,n.eq)(d.userId,a),(0,n.isNull)(f.hubId)))))[0]??null},ut=async r=>{let a=s.attachment;if(!a)return;let o=new Date;try{await e.update(a).set({objectCheckedAt:o,objectMissingAt:o,updatedAt:o}).where((0,n.eq)(a.id,r))}catch(c){W.error("markAttachmentMissing failed",c)}},dt=async r=>{let a=s.attachment;if(!a)return;let o=new Date;try{await e.update(a).set({objectCheckedAt:o,objectMissingAt:null,updatedAt:o}).where((0,n.eq)(a.id,r))}catch(c){W.error("markAttachmentPresent failed",c)}},ct=async(r,a,{forceRefresh:o=!1,snapshot:c=!1,ttlMsOverride:f}={})=>{let g=await re(a);if(!g)return[];let w=Z(r);if(!w)return[];let M=`daily-report:date:${w}:user:${g}`;return y.getOrFetch({cacheKey:M,fetcher:async()=>{let F=await de(),j=(0,n.aliasedTable)(J,"draft_label"),H=await q(e.select({hub:me(d),internal:me(P),isRead:Y.isRead,isStarred:Y.isStarred,creatorName:i.displayName,...b()}).from(d)).leftJoin(P,(0,n.eq)(d.id,P.hubId)).leftJoin(Y,(0,n.and)((0,n.eq)(d.id,Y.hubId),(0,n.eq)(Y.userId,g))).leftJoin(j,(0,n.and)((0,n.eq)(j.hubId,d.id),(0,n.inArray)(j.labelId,F))).leftJoin(i,(0,n.eq)(d.userId,i.id)).where((0,n.and)((0,n.eq)(d.businessDate,n.sql`${w}`),(0,n.isNull)(d.deletedAt),(0,n.or)((0,n.eq)(d.userId,g),(0,n.isNull)(j.hubId)))).orderBy((0,n.desc)(d.id));if(H.length===0)return[];let ee=H.map(z=>z.hub.id),le=await e.select({hubId:J.hubId,id:K.id,name:K.name,color:K.color}).from(J).innerJoin(K,(0,n.eq)(J.labelId,K.id)).where((0,n.inArray)(J.hubId,ee)),ce=await e.select({hubId:h.hubId,id:h.id,body:h.body,createdAt:h.createdAt,userId:h.userId,userName:i.displayName}).from(h).leftJoin(i,(0,n.eq)(h.userId,i.id)).where((0,n.inArray)(h.hubId,ee)).orderBy((0,n.asc)(h.createdAt)),ye=await Ce(ee),ue=new Map,V=new Map;for(let z of le){let Q=ue.get(z.hubId);Q||(Q=[],ue.set(z.hubId,Q)),Q.push({id:z.id,name:z.name,color:z.color})}for(let z of ce){let Q=V.get(z.hubId);Q||(Q=[],V.set(z.hubId,Q)),Q.push({id:z.id,content:z.body,createdAt:I(z.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:z.userId,userName:z.userName||""})}return H.map(z=>{let Q=z.hub.id;return O({...z,attachments:ye.get(Q)??[],labels:ue.get(Q)||[],comments:V.get(Q)||[]},g)})},forceRefresh:o,snapshot:c,ttlMsOverride:f??x,epochKey:`${R}${w}`})},be=async(r,a,{forceRefresh:o=!1,snapshot:c=!1,ttlMsOverride:f}={})=>{let g=`daily-report:detail:${r}:user:${a}`;return(await y.getOrFetch({cacheKey:g,fetcher:async()=>{let M=await de(),F=(0,n.aliasedTable)(J,"draft_label"),j=await q(e.select({hub:me(d),internal:me(P),isRead:Y.isRead,isStarred:Y.isStarred,creatorName:i.displayName,...b()}).from(d)).leftJoin(P,(0,n.eq)(d.id,P.hubId)).leftJoin(Y,(0,n.and)((0,n.eq)(d.id,Y.hubId),(0,n.eq)(Y.userId,a))).leftJoin(F,(0,n.and)((0,n.eq)(F.hubId,d.id),(0,n.inArray)(F.labelId,M))).leftJoin(i,(0,n.eq)(d.userId,i.id)).where((0,n.and)((0,n.eq)(d.id,r),(0,n.isNull)(d.deletedAt),(0,n.or)((0,n.eq)(d.userId,a),(0,n.isNull)(F.hubId))));if(j.length===0)return[];let H=j[0].hub.id,ee=await e.select({id:K.id,name:K.name,color:K.color}).from(J).innerJoin(K,(0,n.eq)(J.labelId,K.id)).where((0,n.eq)(J.hubId,H)),le=await e.select({id:h.id,body:h.body,createdAt:h.createdAt,userId:h.userId,userName:i.displayName}).from(h).leftJoin(i,(0,n.eq)(h.userId,i.id)).where((0,n.eq)(h.hubId,H)).orderBy((0,n.asc)(h.createdAt)),ce=await Ce([H]),ye=ee.map(V=>({id:V.id,name:V.name,color:V.color})),ue=le.map(V=>({id:V.id,content:V.body,createdAt:I(V.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:V.userId,userName:V.userName||""}));return[O({...j[0],attachments:ce.get(H)??[],labels:ye,comments:ue},a)]},forceRefresh:o,snapshot:c,ttlMsOverride:f??x,epochKey:`${_}${r}`}))[0]??null},mt=async(r,a,o={})=>{let c=await re(a);return c?be(r,c,o):null},pt=async(r,a,o,c,f)=>{let g=await e.select().top(1).from(Y).where((0,n.and)((0,n.eq)(Y.hubId,a),(0,n.eq)(Y.userId,r))),w;if(g.length>0?g[0].isStarred!==c?w=(await e.update(Y).set({isStarred:c,updatedAt:new Date,updatedBy:String(r)}).output().where((0,n.and)((0,n.eq)(Y.hubId,a),(0,n.eq)(Y.userId,r))))[0]:w=g[0]:w=(await e.insert(Y).output().values({hubId:a,userId:r,isStarred:c,isRead:!1,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}))[0],o){let M=Z(o);M&&(y.invalidate(`daily-report:date:${M}:user:${r}`),await D(`${R}${M}`))}return y.invalidate(`daily-report:detail:${a}`),y.invalidate(`daily-report:detail:${a}:user:${r}`),await D(`${_}${a}`),await S(Me.parse({type:"status-update",reportHubId:a,recipientRawUserId:r,statusType:"star",value:c,clientTempId:f}),"setStarStatus"),w},yt=async(r,a,o,c,f)=>{let g=await e.select().top(1).from(Y).where((0,n.and)((0,n.eq)(Y.hubId,a),(0,n.eq)(Y.userId,r))),w;if(g.length>0?g[0].isRead!==c?w=(await e.update(Y).set({isRead:c,updatedAt:new Date,updatedBy:String(r)}).output().where((0,n.and)((0,n.eq)(Y.hubId,a),(0,n.eq)(Y.userId,r))))[0]:w=g[0]:w=(await e.insert(Y).output().values({hubId:a,userId:r,isRead:c,isStarred:!1,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}))[0],o){let M=Z(o);M&&(y.invalidate(`daily-report:date:${M}:user:${r}`),await D(`${R}${M}`))}return y.invalidate(`daily-report:detail:${a}`),y.invalidate(`daily-report:detail:${a}:user:${r}`),await D(`${_}${a}`),await S(Me.parse({type:"status-update",reportHubId:a,recipientRawUserId:r,statusType:"read",value:c,clientTempId:f}),"setReadStatus"),w},ht=async(r,a,o,c,f)=>{let[g]=await e.select({sourceType:d.sourceType}).top(1).from(d).where((0,n.eq)(d.id,a));if(g&&g.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let[w]=await e.insert(h).output().values({hubId:a,userId:r,body:o,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}),[M]=await e.select({displayName:i.displayName}).top(1).from(i).where((0,n.eq)(i.id,r)),F=M?.displayName??"Unknown";if(c){let H=Z(c);H&&(y.invalidatePrefix(`daily-report:date:${H}:user:`),await D(`${R}${H}`))}y.invalidate(`daily-report:detail:${a}`),y.invalidatePrefix(`daily-report:detail:${a}:user:`),await D(`${_}${a}`);let j={id:w.id,userId:m(w.userId),userName:F,content:w.body,createdAt:I(w.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await S(Be.parse({type:"comment-add",reportHubId:a,comment:j,clientTempId:f}),"addComment"),j},ft=async(r,a)=>await r.select().top(1).from(h).where((0,n.eq)(h.id,a)),gt=async(r,a,o,c,f)=>{let g=await ft(e,o);if(g.length===0)throw new Error("Not Found");if(g[0].userId!==r)throw new Error("Unauthorized");if(await e.delete(h).where((0,n.eq)(h.id,o)),c){let w=Z(c);w&&(y.invalidatePrefix(`daily-report:date:${w}:user:`),await D(`${R}${w}`))}y.invalidate(`daily-report:detail:${a}`),y.invalidatePrefix(`daily-report:detail:${a}:user:`),await D(`${_}${a}`),await S(Ue.parse({type:"comment-delete",reportHubId:a,commentId:o,clientTempId:f}),"deleteComment")},bt=async(r,a,o)=>{W.info("createDailyReport called",{userId:r,businessDate:a});let[c]=await e.select({displayName:i.displayName}).from(i).where((0,n.eq)(i.id,r)),f=c?.displayName??m(r);try{let g=await e.transaction(async F=>{W.info("Starting transaction");let j=`internal-temp-${Date.now()}-${Math.random()}`,[H]=await F.insert(d).output().values({sourceType:"Internal",sourceId:j,businessDate:new Date(a),userId:r,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)});await F.update(d).set({sourceId:String(H.id)}).where((0,n.eq)(d.id,H.id)),W.info("Hub created",H),await F.insert(P).values({hubId:H.id,body:"",createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}),W.info("Internal created"),W.info("Calling getDraftLabelId");let ee=await ve();W.info("draftLabelId",ee);let le=[];return ee&&(await F.insert(J).values({hubId:H.id,labelId:ee,createdAt:new Date,createdBy:String(r)}),le.push({id:ee,name:_e,color:null})),W.info("Label assigned"),{reportHubId:H.id,date:a,createdAt:I(H.createdAt,"YYYY-MM-DD HH:mm:ss"),author:f,userId:m(r),sourceType:"Internal",employeeName:f,updatedBy:m(r),updatedAt:I(H.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:H.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:le,commentItems:[],attachments:[]}}),w=Z(a);w&&y.invalidate(`daily-report:date:${w}:user:${r}`),y.invalidatePrefix(E),y.invalidate(`${fe}:user:${r}`),await D(B),w&&await D(`${R}${w}`);let M=await be(g.reportHubId,r,{forceRefresh:!0});if(M){let F=await oe(),j=M.labels.some(H=>F.includes(H.id));await S(He.parse({type:"report-create",reportHubId:M.reportHubId,report:M,clientTempId:o,recipientRawUserId:j?r:void 0}),"createDailyReport")}return M??g}catch(g){throw W.error("Error in createDailyReport",g),g}},Te=async(r,a)=>await r.select().top(1).from(d).where((0,n.eq)(d.id,a)),Ne=async(r,a,o)=>{await r.update(d).set(o).where((0,n.eq)(d.id,a))},Je=async(r,a,o)=>{await r.update(P).set(o).where((0,n.eq)(P.hubId,a))},je=async(r,a,o)=>{await r.delete(J).where((0,n.and)((0,n.eq)(J.hubId,a),(0,n.eq)(J.labelId,o)))};return{streamKey:N,streamMaxLen:T,clearCache:async()=>{y.clearAll(),se.clear(),ie=null,$&&await D(B),W.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(r,a)=>{y.invalidatePrefix(E);for(let o of new Set(r))y.invalidatePrefix(`daily-report:detail:${o}:user:`),await D(`${_}${o}`);for(let o of new Set(a)){let c=Z(o);c&&await D(`${R}${c}`)}},getUserIdByExternalId:re,getDailyReportIdsByExternalId:ge,getDailyReportIdsFirstPageByExternalId:C,getDailyReportsByBusinessDate:pe,getDailyReportsByBusinessDateByExternalId:ct,getDailyReportDetailById:be,getDailyReportDetailByIdByExternalId:mt,getDraftLabelId:ve,getAttachmentsByHubIds:Ce,getAttachmentForUser:lt,markAttachmentMissing:ut,markAttachmentPresent:dt,setStarStatus:pt,setReadStatus:yt,addComment:ht,deleteComment:gt,createDailyReport:bt,updateDailyReport:async(r,a,o,c)=>{let f=await Te(e,r);if(!f.length||f[0].deletedAt)throw new Error("Not Found");if(f[0].userId!==a)throw new Error("Unauthorized");await e.transaction(async w=>{o.title!==void 0&&await Ne(w,r,{title:o.title,updatedAt:new Date,updatedBy:String(a)}),o.content!==void 0&&await Je(w,r,{body:o.content,updatedAt:new Date,updatedBy:String(a)})}),y.invalidatePrefix(`daily-report:detail:${r}:user:`),y.invalidatePrefix(E);let g=await be(r,a,{forceRefresh:!0});if(g){let w=await oe(),M=g.labels.some(F=>w.includes(F.id));await S(Ye.parse({type:"report-update",reportHubId:g.reportHubId,report:g,clientTempId:c,recipientRawUserId:M?a:void 0}),"updateDailyReport")}},publishDailyReport:async(r,a,o)=>{let c=await Te(e,r);if(!c.length)throw new Error("Not Found");if(c[0].userId!==a)throw new Error("Unauthorized");let f=await ve();if(!f)return null;if(await je(e,r,f),y.invalidatePrefix(`daily-report:detail:${r}:user:`),y.invalidatePrefix(E),y.invalidatePrefix(fe),await D(B),c[0].businessDate){let M=Z(I(c[0].businessDate,"YYYY-MM-DD"));M&&await D(`${R}${M}`)}let g=Z(I(c[0].businessDate,"YYYY-MM-DD"));g&&y.invalidate(`daily-report:date:${g}:user:${a}`);let w=await be(r,a,{forceRefresh:!0});return w&&await S(qe.parse({type:"report-publish",reportHubId:w.reportHubId,report:w,clientTempId:o}),"publishDailyReport"),w??null},deleteDailyReport:async(r,a,o)=>{let c=await Te(e,r);if(!c.length||c[0].deletedAt)throw new Error("Not Found");if(c[0].userId!==a)throw new Error("Unauthorized");if(await Ne(e,r,{deletedAt:new Date,deletedBy:String(a),updatedAt:new Date,updatedBy:String(a)}),y.invalidatePrefix(`daily-report:detail:${r}:user:`),y.invalidatePrefix(E),y.invalidatePrefix(fe),await D(B),c[0].businessDate){let f=Z(I(c[0].businessDate,"YYYY-MM-DD"));f&&await D(`${R}${f}`)}await S(Oe.parse({type:"report-delete",reportHubId:r,clientTempId:o}),"deleteDailyReport")},findDailyReportHubById:Te,updateDailyReportHub:Ne,updateDailyReportInternal:Je,deleteDailyReportLabel:je}}var Se=require("drizzle-orm");function ot(t){let e=[],s=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let i of s){let m=`daily_report_${i.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:m,name:i.name,description:i.description??`${i.name} daily report access`}),i.includeCommentResource!==!1&&e.push({resourceKey:`${m}_comment`,name:`${i.name} Comment`,description:`${i.name} daily report comment access`})}return e}async function Vt(t,e,s){let i=t,p=e.TMResource,m=s.appKey,v=s.actor??"system:daily-report",y=new Date,$=s.resources??ot(s.sources);for(let d of $){let P=await i.select().from(p).where((0,Se.and)((0,Se.eq)(p.appKey,m),(0,Se.eq)(p.resourceKey,d.resourceKey)));(!P||P.length===0)&&await i.insert(p).values({appKey:m,resourceKey:d.resourceKey,name:d.name,description:d.description??null,createdAt:y,createdBy:v,updatedAt:y,updatedBy:v})}}var Zt=ne(1,"[DailyReportExternalSource]"),er=(t,e,s,i=Zt)=>{if(!t)return[];try{let p=JSON.parse(t);return Array.isArray(p)?p.map(s).filter(m=>m!==null):(i.warn(`Unexpected ${e} format: not an array`),[])}catch(p){return i.warn(`Failed to parse ${e}:`,p),[]}};var Ie=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function tr(t,e){let s=(0,l.mssqlSchema)(t),i=e.userTable,p=s.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(Ie.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})},h=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_user_id_fk`,columns:[h.userId],foreignColumns:[i.id]}),(0,l.index)(`${t}_DailyReportHub_business_date_index`).on(h.businessDate),(0,l.index)(`${t}_DailyReportHub_updated_at_index`).on(h.updatedAt),(0,l.index)(`${t}_DailyReportHub_source_index`).on(h.sourceType,h.sourceId),(0,l.index)(`${t}_DailyReportHub_user_id_index`).on(h.userId),(0,l.index)(`${t}_DailyReportHub_business_date_id_index`).on((0,Ie.desc)(h.businessDate),(0,Ie.desc)(h.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(h.deletedAt)]),m=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportInternal_pk`,columns:[h.hubId]}),(0,l.foreignKey)({name:`${t}_DailyReportInternal_hub_id_fk`,columns:[h.hubId],foreignColumns:[p.id]})]),v=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportComment_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_hub_id_fk`,columns:[h.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[h.userId],foreignColumns:[i.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(h.hubId)]),y=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportLabel_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportLabel_user_id_fk`,columns:[h.userId],foreignColumns:[i.id]})]),$=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportHub_Label_pk`,columns:[h.hubId,h.labelId]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_hub_id_fk`,columns:[h.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[h.labelId],foreignColumns:[y.id]})]),d=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportUserStatus_pk`,columns:[h.hubId,h.userId]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_hub_id_fk`,columns:[h.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[h.userId],foreignColumns:[i.id]})]),P=s.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()},h=>[(0,l.primaryKey)({name:`${t}_DailyReportAttachment_pk`,columns:[h.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_hub_id_fk`,columns:[h.hubId],foreignColumns:[p.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[h.uploadedBy],foreignColumns:[i.id]}),(0,l.uniqueIndex)(`${t}_DailyReportAttachment_source_unique`).on(h.hubId,h.sourceKey),(0,l.index)(`${t}_DailyReportAttachment_hub_id_index`).on(h.hubId,h.createdAt)]);return{hub:p,internal:m,comment:v,attachment:P,label:y,hubLabel:$,userStatus:d}}function rr(t){let e=$e(t.redis),s=new Re({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),i=Ke({...t,cache:s,epochs:e}),p=new De({redis:t.redis,streamKey:i.streamKey,cache:s,logger:t.logger}),m=ze({authenticate:t.authenticate,service:i,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:p,streamKey:i.streamKey,loginRedirectPath:t.loginRedirectPath,logger:t.logger});return{service:i,cache:s,epochs:e,sseReader:p,streamKey:i.streamKey,...m}}0&&(module.exports={DailyReportSseReader,SqlResultCache,asciiFallbackFileName,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,encodeRfc8187,generateETag,isStreamIdLte,jsonResponseWithETag,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
11
+ `,W=G!=="0-0"?`id: ${G}
12
+ ${T}`:T;E.enqueue($.encode(W))}if(C)try{let T=await y?.getClient();if(T){let W=await T.xRange(M,C,"+",{COUNT:1e3});for(let te of W)te.id!==C&&(we(te.id,G)||(G=te.id,g(te.id,te.message)))}}catch(T){u.error(`[SSE:${x}] catch-up xRange error:`,T)}},cancel(){_()}});return new Response(P,{headers:{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive"}})}},attachment:{loader:async({request:k,params:H})=>{let v=null,x=(R,C,$)=>{let E=new Headers({"Content-Type":"application/json"});return $!==void 0&&E.set("Retry-After",String($)),v&&E.append("Set-Cookie",v),new Response(JSON.stringify({error:{message:C}}),{status:R,headers:E})};try{let{user:R,cookie:C}=await e(k,{failureRedirect:null});if(v=C??null,!R)return x(401,"Unauthorized");if(k.method!=="GET"&&k.method!=="HEAD")return x(405,"Method not allowed");let $=t.attachmentIdCodec,E=t.readAttachment;if(!($&&E))return x(404,"Attachment not found");let D=H.token??"",w=$.decode(D);if(w===null||!Number.isSafeInteger(w)||w<=0)return x(400,"Invalid attachment token");let I=await s.getUserIdByExternalId(R.id);if(!I)return x(403,"Forbidden");if(!K(I,Date.now()))return N.error(`429 attachment=${w} viewer=${I} reason=rate_limit`),x(429,"Too many requests",Kt);let _=await s.getAttachmentForUser(w,I);if(!_)return N.error(`404 attachment=${w} viewer=${I} reason=not_visible`),x(404,"Attachment not found");if(_.fileSize!=null&&_.fileSize>p)return N.error(`413 attachment=${w} viewer=${I} reason=db_size`),x(413,"Attachment too large");if(!q.tryAcquire())return N.error(`503 attachment=${w} viewer=${I} reason=concurrency`),x(503,"Too many concurrent downloads",Jt);let g=!1,P=()=>{g||(g=!0,q.release())},F=!1;try{let G=k.method==="HEAD",T=await E(_.filePath,{maxBytes:p,head:G,principal:i(I)});if(!T.ok){let oe=Xt(T.reason);return T.reason==="not_found"&&s.markAttachmentMissing(w).catch(le=>{N.error(`markAttachmentMissing failed attachment=${w} message=${le instanceof Error?le.message:"unknown"}`)}),N.error(`${oe} attachment=${w} viewer=${I} reason=${T.reason} code=${T.code??"-"}`),x(oe,Wt[oe]??"Attachment storage unavailable")}let W=Fe(_.fileType)??Fe(T.contentType)??"application/octet-stream",te=jt.has(W),se=new URL(k.url).searchParams.get("download")==="1",re=te?W:"application/octet-stream",be=te&&!se?"inline":"attachment",ye=T.size??T.bytes.byteLength,ie=new Headers({"Content-Type":re,"Content-Length":String(ye),"Content-Disposition":`${be}; filename="${it(_.fileName)}"; filename*=UTF-8''${ot(_.fileName)}`,"Cache-Control":"private, no-store","X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; sandbox","X-Frame-Options":"SAMEORIGIN"});return v&&ie.append("Set-Cookie",v),s.markAttachmentPresent(w).catch(oe=>{N.error(`markAttachmentPresent failed attachment=${w} message=${oe instanceof Error?oe.message:"unknown"}`)}),N.info(`200 attachment=${w} viewer=${I} type=${re} disposition=${be} bytes=${ye}`),G?new Response(null,{status:200,headers:ie}):(F=!0,new Response(er(T.bytes,P,Ft),{status:200,headers:ie}))}finally{F||P()}}catch(R){if(R instanceof Response)throw R;return N.error(`500 attachment=? viewer=? reason=unexpected message=${R instanceof Error?R.message:"unknown"}`),x(500,"Attachment request failed")}}}}}var n=require("drizzle-orm");var pe=t=>(0,n.getColumns)(t);function Ke(t){let{db:e,tables:s,userTable:i,resolveUserId:y,encodeUserId:m,redis:M,cache:h,epochs:O}=t,{hub:u,internal:N,comment:p,label:K,hubLabel:q,userStatus:U}=s,me=t.externalSources??[],Ae=t.draftLabelNames&&t.draftLabelNames.length>0?t.draftLabelNames:[t.draftLabelName??"\u4E0B\u66F8\u304D"],Ce=Ae[0]??"\u4E0B\u66F8\u304D",V=t.logger??ne(1,"[DailyReportService]"),fe="daily-report:ids",k=t.idsTtlMs??18e4,H="daily-report:ids:epoch",v="daily-report:business-date:",x=t.businessDateTtlMs??3e5,R="daily-report:date-epoch:",C="daily-report:detail-epoch:",$=t.streamKey??"daily-report:sse-stream",E=t.streamMaxLen??1e4,D=r=>O.incrementEpoch(r),w=async(r,a)=>{let o=await M?.getClient();if(!o){V.warn(`[SSE] Redis client unavailable (${a})`);return}let c=Date.now();try{await o.xAdd($,"*",{data:JSON.stringify(r)},{TRIM:{strategy:"MAXLEN",strategyModifier:"~",threshold:E}});let b=Date.now()-c;b>1e3&&V.warn(`[SSE] Slow publish (${a}): ${b}ms`)}catch(b){V.error(`[SSE] Redis publish failed (${a}):`,b)}},I=(r,a)=>{if(!r)return null;let o=r instanceof Date?r:new Date(r);if(Number.isNaN(o.getTime()))return typeof r=="string"?r:null;let c=a==="YYYY-MM-DD HH:mm:ss"?{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"}:{year:"numeric",month:"2-digit",day:"2-digit"};return(a==="YYYY-MM-DD HH:mm:ss"?o.toLocaleString("ja-JP",c):o.toLocaleDateString("ja-JP",c)).replace(/\//g,"-")},_=r=>r==null||r===""?null:/^\d+$/.test(r)?m(Number(r)):r,g=()=>{let r={};for(let a of me)r[`ext_${a.sourceType}`]=pe(a.table);return r},P=r=>{let a=r;for(let o of me)a=a.leftJoin(o.table,(0,n.and)((0,n.eq)(u.sourceType,o.sourceType),(0,n.eq)(u.sourceIdNum,o.idColumn)));return a},F=(r,a)=>{let{hub:o,internal:c}=r,b=o.summary,f=[],S=null,A=null,z=null,j=null,Y=null,Q=null,ue=[],ce=me.find(B=>B.sourceType===o.sourceType),he=ce?r[`ext_${ce.sourceType}`]:void 0;if(ce&&he){let B=ce.mapRow(he);B.content!==void 0&&(b=B.content),B.employeeName!==void 0&&(Q=B.employeeName),B.category!==void 0&&(S=B.category),B.creationCategory!==void 0&&(A=B.creationCategory),B.visitTimeFrom!==void 0&&(z=B.visitTimeFrom),B.visitTimeTo!==void 0&&(j=B.visitTimeTo),B.customerName!==void 0&&(Y=B.customerName),B.interviewers!==void 0&&(f=B.interviewers),B.comments!==void 0&&(ue=B.comments)}else o.sourceType==="Internal"&&c&&(b=c.body);let de=(r.labels??[]).map(B=>({id:B.id,name:B.name,color:B.color})),Z=r.comments??[],J=A?Ae.includes(A):!1,X=ie?.[0]??null;return J&&X&&!de.some(B=>B.id===X)&&de.push({id:X,name:Ce,color:null}),{reportHubId:o.id,date:I(o.businessDate,"YYYY-MM-DD"),author:r.creatorName??_(o.createdBy)??"",userId:o.userId?m(o.userId):"",sourceType:o.sourceType??"Internal",createdAt:I(o.createdAt,"YYYY-MM-DD HH:mm:ss"),updatedAt:I(o.updatedAt,"YYYY-MM-DD HH:mm:ss"),updatedBy:_(o.updatedBy),employeeName:Q??r.creatorName??_(o.createdBy),category:S,creationCategory:A,visitTimeFrom:z,visitTimeTo:j,customerName:Y,interviewers:f,subject:o.title,content:b,comments:ue,isRead:r.isRead??!1,isStarred:r.isStarred??!1,labels:de,commentItems:Z.map(B=>({...B,userId:m(B.userId),isMine:a?B.userId===a:!1})),attachments:r.attachments}},G=async r=>{let a=(0,n.aliasedTable)(q,"draft_label"),o=await le();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).from(u).leftJoin(a,(0,n.and)((0,n.eq)(a.hubId,u.id),(0,n.inArray)(a.labelId,o))).where((0,n.and)((0,n.isNull)(u.deletedAt),(0,n.or)((0,n.eq)(u.userId,r),(0,n.isNull)(u.userId),(0,n.isNull)(a.hubId)))).orderBy((0,n.desc)(u.businessDate),(0,n.desc)(u.id))).map(b=>({...b,businessDate:I(b.businessDate,"YYYY-MM-DD")}))},T=async(r,a)=>{let o=await re(r);if(!o)return[];let c=(0,n.aliasedTable)(q,"draft_label"),b=await le();return(await e.select({reportHubId:u.id,businessDate:u.businessDate,sourceType:u.sourceType}).top(a).from(u).leftJoin(c,(0,n.and)((0,n.eq)(c.hubId,u.id),(0,n.inArray)(c.labelId,b))).where((0,n.and)((0,n.isNull)(u.deletedAt),(0,n.or)((0,n.eq)(u.userId,o),(0,n.isNull)(u.userId),(0,n.isNull)(c.hubId)))).orderBy((0,n.desc)(u.businessDate),(0,n.desc)(u.id))).map(S=>({...S,businessDate:I(S.businessDate,"YYYY-MM-DD")}))},W=async r=>{let a=await P(e.select({hub:pe(u),internal:pe(N),creatorName:i.displayName,...g()}).from(u)).leftJoin(N,(0,n.eq)(u.id,N.hubId)).leftJoin(i,(0,n.eq)(u.userId,i.id)).where((0,n.and)((0,n.eq)(u.businessDate,n.sql`${r}`),(0,n.isNull)(u.deletedAt))).orderBy((0,n.desc)(u.id)),o=await _e(a.map(c=>c.hub.id));return a.map(c=>F({...c,attachments:o.get(c.hub.id)??[]}))},te=r=>`${v}${r}`,se=new Map,re=async r=>{if(!t.disableUserIdCache&&se.has(r))return se.get(r)??null;let a=await y(r);return a!==null&&!t.disableUserIdCache&&se.set(r,a),a},be=async(r,{forceRefresh:a=!1,snapshot:o=!1,ttlMsOverride:c}={})=>{let b=await re(r);if(!b)return[];let f=`${fe}:user:${b}`;return h.getOrFetch({cacheKey:f,fetcher:async()=>await G(b),forceRefresh:a,snapshot:o,ttlMsOverride:c??k,epochKey:H})},ye=(r,{forceRefresh:a=!1,snapshot:o=!1,ttlMsOverride:c}={})=>{let b=ee(r);return b?h.getOrFetch({cacheKey:te(b),fetcher:()=>W(b),forceRefresh:a,snapshot:o,ttlMsOverride:c??x}):Promise.resolve([])},ie=null,oe=async()=>(ie!==null||(ie=(await e.select({id:K.id}).from(K).where((0,n.inArray)(K.name,Ae)).orderBy(K.id)).map(a=>a.id)),ie),le=async()=>{let r=await oe();return r.length>0?r:[-1]},xe=async()=>{let r=await oe();if(r.length===0)return null;let[a]=await e.select({id:K.id}).top(1).from(K).where((0,n.eq)(K.name,Ce));return a?.id??r[0]},ut=(r,a)=>a!=null?"absent":r!=null?"present":"unknown",_e=async r=>{let a=new Map,o=s.attachment,c=t.attachmentIdCodec;if(r.length===0||!o||!c)return a;let b=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,n.inArray)(o.hubId,r)).orderBy((0,n.asc)(o.createdAt),(0,n.asc)(o.id));for(let f of b){let S={id:c.encode(Number(f.id)),fileName:String(f.fileName),fileType:f.fileType?String(f.fileType):null,fileSize:f.fileSize!=null?Number(f.fileSize):null,createdAt:I(f.createdAt,"YYYY-MM-DD HH:mm:ss"),state:ut(f.objectCheckedAt,f.objectMissingAt)},A=a.get(Number(f.hubId));A?A.push(S):a.set(Number(f.hubId),[S])}return a},dt=async(r,a)=>{let o=s.attachment;if(!o)return null;let c=await le(),b=(0,n.aliasedTable)(q,"draft_label");return(await e.select({fileName:o.fileName,filePath:o.filePath,fileType:o.fileType,fileSize:o.fileSize}).top(1).from(o).innerJoin(u,(0,n.eq)(u.id,o.hubId)).leftJoin(b,(0,n.and)((0,n.eq)(b.hubId,u.id),(0,n.inArray)(b.labelId,c))).where((0,n.and)((0,n.eq)(o.id,r),(0,n.isNull)(u.deletedAt),(0,n.or)((0,n.eq)(u.userId,a),(0,n.isNull)(b.hubId)))))[0]??null},ct=async r=>{let a=s.attachment;if(!a)return;let o=new Date;try{await e.update(a).set({objectCheckedAt:o,objectMissingAt:o,updatedAt:o}).where((0,n.eq)(a.id,r))}catch(c){V.error("markAttachmentMissing failed",c)}},mt=async r=>{let a=s.attachment;if(!a)return;let o=new Date;try{await e.update(a).set({objectCheckedAt:o,objectMissingAt:null,updatedAt:o}).where((0,n.eq)(a.id,r))}catch(c){V.error("markAttachmentPresent failed",c)}},pt=async(r,a,{forceRefresh:o=!1,snapshot:c=!1,ttlMsOverride:b}={})=>{let f=await re(a);if(!f)return[];let S=ee(r);if(!S)return[];let A=`daily-report:date:${S}:user:${f}`;return h.getOrFetch({cacheKey:A,fetcher:async()=>{let z=await le(),j=(0,n.aliasedTable)(q,"draft_label"),Y=await P(e.select({hub:pe(u),internal:pe(N),isRead:U.isRead,isStarred:U.isStarred,creatorName:i.displayName,...g()}).from(u)).leftJoin(N,(0,n.eq)(u.id,N.hubId)).leftJoin(U,(0,n.and)((0,n.eq)(u.id,U.hubId),(0,n.eq)(U.userId,f))).leftJoin(j,(0,n.and)((0,n.eq)(j.hubId,u.id),(0,n.inArray)(j.labelId,z))).leftJoin(i,(0,n.eq)(u.userId,i.id)).where((0,n.and)((0,n.eq)(u.businessDate,n.sql`${S}`),(0,n.isNull)(u.deletedAt),(0,n.or)((0,n.eq)(u.userId,f),(0,n.isNull)(j.hubId)))).orderBy((0,n.desc)(u.id));if(Y.length===0)return[];let Q=Y.map(J=>J.hub.id),ue=await e.select({hubId:q.hubId,id:K.id,name:K.name,color:K.color}).from(q).innerJoin(K,(0,n.eq)(q.labelId,K.id)).where((0,n.inArray)(q.hubId,Q)),ce=await e.select({hubId:p.hubId,id:p.id,body:p.body,createdAt:p.createdAt,userId:p.userId,userName:i.displayName}).from(p).leftJoin(i,(0,n.eq)(p.userId,i.id)).where((0,n.inArray)(p.hubId,Q)).orderBy((0,n.asc)(p.createdAt)),he=await _e(Q),de=new Map,Z=new Map;for(let J of ue){let X=de.get(J.hubId);X||(X=[],de.set(J.hubId,X)),X.push({id:J.id,name:J.name,color:J.color})}for(let J of ce){let X=Z.get(J.hubId);X||(X=[],Z.set(J.hubId,X)),X.push({id:J.id,content:J.body,createdAt:I(J.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:J.userId,userName:J.userName||""})}return Y.map(J=>{let X=J.hub.id;return F({...J,attachments:he.get(X)??[],labels:de.get(X)||[],comments:Z.get(X)||[]},f)})},forceRefresh:o,snapshot:c,ttlMsOverride:b??x,epochKey:`${R}${S}`})},ge=async(r,a,{forceRefresh:o=!1,snapshot:c=!1,ttlMsOverride:b}={})=>{let f=`daily-report:detail:${r}:user:${a}`;return(await h.getOrFetch({cacheKey:f,fetcher:async()=>{let A=await le(),z=(0,n.aliasedTable)(q,"draft_label"),j=await P(e.select({hub:pe(u),internal:pe(N),isRead:U.isRead,isStarred:U.isStarred,creatorName:i.displayName,...g()}).from(u)).leftJoin(N,(0,n.eq)(u.id,N.hubId)).leftJoin(U,(0,n.and)((0,n.eq)(u.id,U.hubId),(0,n.eq)(U.userId,a))).leftJoin(z,(0,n.and)((0,n.eq)(z.hubId,u.id),(0,n.inArray)(z.labelId,A))).leftJoin(i,(0,n.eq)(u.userId,i.id)).where((0,n.and)((0,n.eq)(u.id,r),(0,n.isNull)(u.deletedAt),(0,n.or)((0,n.eq)(u.userId,a),(0,n.isNull)(z.hubId))));if(j.length===0)return[];let Y=j[0].hub.id,Q=await e.select({id:K.id,name:K.name,color:K.color}).from(q).innerJoin(K,(0,n.eq)(q.labelId,K.id)).where((0,n.eq)(q.hubId,Y)),ue=await e.select({id:p.id,body:p.body,createdAt:p.createdAt,userId:p.userId,userName:i.displayName}).from(p).leftJoin(i,(0,n.eq)(p.userId,i.id)).where((0,n.eq)(p.hubId,Y)).orderBy((0,n.asc)(p.createdAt)),ce=await _e([Y]),he=Q.map(Z=>({id:Z.id,name:Z.name,color:Z.color})),de=ue.map(Z=>({id:Z.id,content:Z.body,createdAt:I(Z.createdAt,"YYYY-MM-DD HH:mm:ss")||"",userId:Z.userId,userName:Z.userName||""}));return[F({...j[0],attachments:ce.get(Y)??[],labels:he,comments:de},a)]},forceRefresh:o,snapshot:c,ttlMsOverride:b??x,epochKey:`${C}${r}`}))[0]??null},yt=async(r,a,o={})=>{let c=await re(a);return c?ge(r,c,o):null},ht=async(r,a,o,c,b)=>{let f=await e.select().top(1).from(U).where((0,n.and)((0,n.eq)(U.hubId,a),(0,n.eq)(U.userId,r))),S;if(f.length>0?f[0].isStarred!==c?S=(await e.update(U).set({isStarred:c,updatedAt:new Date,updatedBy:String(r)}).output().where((0,n.and)((0,n.eq)(U.hubId,a),(0,n.eq)(U.userId,r))))[0]:S=f[0]:S=(await e.insert(U).output().values({hubId:a,userId:r,isStarred:c,isRead:!1,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}))[0],o){let A=ee(o);A&&(h.invalidate(`daily-report:date:${A}:user:${r}`),await D(`${R}${A}`))}return h.invalidate(`daily-report:detail:${a}`),h.invalidate(`daily-report:detail:${a}:user:${r}`),await D(`${C}${a}`),await w(Me.parse({type:"status-update",reportHubId:a,recipientRawUserId:r,statusType:"star",value:c,clientTempId:b}),"setStarStatus"),S},ft=async(r,a,o,c,b)=>{let f=await e.select().top(1).from(U).where((0,n.and)((0,n.eq)(U.hubId,a),(0,n.eq)(U.userId,r))),S;if(f.length>0?f[0].isRead!==c?S=(await e.update(U).set({isRead:c,updatedAt:new Date,updatedBy:String(r)}).output().where((0,n.and)((0,n.eq)(U.hubId,a),(0,n.eq)(U.userId,r))))[0]:S=f[0]:S=(await e.insert(U).output().values({hubId:a,userId:r,isRead:c,isStarred:!1,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}))[0],o){let A=ee(o);A&&(h.invalidate(`daily-report:date:${A}:user:${r}`),await D(`${R}${A}`))}return h.invalidate(`daily-report:detail:${a}`),h.invalidate(`daily-report:detail:${a}:user:${r}`),await D(`${C}${a}`),await w(Me.parse({type:"status-update",reportHubId:a,recipientRawUserId:r,statusType:"read",value:c,clientTempId:b}),"setReadStatus"),S},Je=async(r,a)=>{if(a===null)return;let o=await le(),[c]=await e.select({hubId:q.hubId}).top(1).from(q).where((0,n.and)((0,n.eq)(q.hubId,r),(0,n.inArray)(q.labelId,o)));return c?a:void 0},bt=async(r,a,o,c,b)=>{let[f]=await e.select({sourceType:u.sourceType,deletedAt:u.deletedAt,userId:u.userId}).top(1).from(u).where((0,n.eq)(u.id,a));if(!f||f.deletedAt)throw new Error("Not Found");if(f.sourceType.toLowerCase()!=="internal")throw new Error("Comments are restricted for external daily report sources");let S=await Je(a,f.userId),[A]=await e.insert(p).output().values({hubId:a,userId:r,body:o,createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}),[z]=await e.select({displayName:i.displayName}).top(1).from(i).where((0,n.eq)(i.id,r)),j=z?.displayName??"Unknown";if(c){let Q=ee(c);Q&&(h.invalidatePrefix(`daily-report:date:${Q}:user:`),await D(`${R}${Q}`))}h.invalidate(`daily-report:detail:${a}`),h.invalidatePrefix(`daily-report:detail:${a}:user:`),await D(`${C}${a}`);let Y={id:A.id,userId:m(A.userId),userName:j,content:A.body,createdAt:I(A.createdAt,"YYYY-MM-DD HH:mm:ss")??"",isMine:!0};return await w(Be.parse({type:"comment-add",reportHubId:a,comment:Y,clientTempId:b,recipientRawUserId:S}),"addComment"),Y},gt=async(r,a)=>await r.select().top(1).from(p).where((0,n.eq)(p.id,a)),Rt=async(r,a,o,c,b)=>{let f=await gt(e,o);if(f.length===0)throw new Error("Not Found");if(f[0].userId!==r)throw new Error("Unauthorized");if(f[0].hubId!==a)throw new Error("Not Found");let[S]=await e.select({userId:u.userId}).top(1).from(u).where((0,n.eq)(u.id,a)),A=await Je(a,S?.userId??null);if(await e.delete(p).where((0,n.eq)(p.id,o)),c){let z=ee(c);z&&(h.invalidatePrefix(`daily-report:date:${z}:user:`),await D(`${R}${z}`))}h.invalidate(`daily-report:detail:${a}`),h.invalidatePrefix(`daily-report:detail:${a}:user:`),await D(`${C}${a}`),await w(Ue.parse({type:"comment-delete",reportHubId:a,commentId:o,clientTempId:b,recipientRawUserId:A}),"deleteComment")},Dt=async(r,a,o)=>{V.info("createDailyReport called",{userId:r,businessDate:a});let[c]=await e.select({displayName:i.displayName}).from(i).where((0,n.eq)(i.id,r)),b=c?.displayName??m(r);try{let f=await e.transaction(async z=>{V.info("Starting transaction");let j=`internal-temp-${Date.now()}-${Math.random()}`,[Y]=await z.insert(u).output().values({sourceType:"Internal",sourceId:j,businessDate:new Date(a),userId:r,title:"(\u7121\u984C)",createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)});await z.update(u).set({sourceId:String(Y.id)}).where((0,n.eq)(u.id,Y.id)),V.info("Hub created",Y),await z.insert(N).values({hubId:Y.id,body:"",createdAt:new Date,createdBy:String(r),updatedAt:new Date,updatedBy:String(r)}),V.info("Internal created"),V.info("Calling getDraftLabelId");let Q=await xe();V.info("draftLabelId",Q);let ue=[];return Q&&(await z.insert(q).values({hubId:Y.id,labelId:Q,createdAt:new Date,createdBy:String(r)}),ue.push({id:Q,name:Ce,color:null})),V.info("Label assigned"),{reportHubId:Y.id,date:a,createdAt:I(Y.createdAt,"YYYY-MM-DD HH:mm:ss"),author:b,userId:m(r),sourceType:"Internal",employeeName:b,updatedBy:m(r),updatedAt:I(Y.updatedAt,"YYYY-MM-DD HH:mm:ss"),category:null,creationCategory:null,visitTimeFrom:null,visitTimeTo:null,customerName:null,interviewers:[],subject:Y.title,content:"",comments:[],isRead:!0,isStarred:!1,labels:ue,commentItems:[],attachments:[]}}),S=ee(a);S&&h.invalidate(`daily-report:date:${S}:user:${r}`),h.invalidatePrefix(v),h.invalidate(`${fe}:user:${r}`),await D(H),S&&await D(`${R}${S}`);let A=await ge(f.reportHubId,r,{forceRefresh:!0});if(A){let z=await oe(),j=A.labels.some(Y=>z.includes(Y.id));await w(He.parse({type:"report-create",reportHubId:A.reportHubId,report:A,clientTempId:o,recipientRawUserId:j?r:void 0}),"createDailyReport")}return A??f}catch(f){throw V.error("Error in createDailyReport",f),f}},Te=async(r,a)=>await r.select().top(1).from(u).where((0,n.eq)(u.id,a)),Ne=async(r,a,o)=>{await r.update(u).set(o).where((0,n.eq)(u.id,a))},je=async(r,a,o)=>{await r.update(N).set(o).where((0,n.eq)(N.hubId,a))},Ge=async(r,a,o)=>{await r.delete(q).where((0,n.and)((0,n.eq)(q.hubId,a),(0,n.eq)(q.labelId,o)))};return{streamKey:$,streamMaxLen:E,clearCache:async()=>{h.clearAll(),se.clear(),ie=null,O&&await D(H),V.info("[DailyReportService] Server-side DB/SQL caches cleared successfully.")},invalidateHubReadCaches:async(r,a)=>{h.invalidatePrefix(v);for(let o of new Set(r))h.invalidatePrefix(`daily-report:detail:${o}:user:`),await D(`${C}${o}`);for(let o of new Set(a)){let c=ee(o);c&&await D(`${R}${c}`)}},getUserIdByExternalId:re,getDailyReportIdsByExternalId:be,getDailyReportIdsFirstPageByExternalId:T,getDailyReportsByBusinessDate:ye,getDailyReportsByBusinessDateByExternalId:pt,getDailyReportDetailById:ge,getDailyReportDetailByIdByExternalId:yt,getDraftLabelId:xe,getAttachmentsByHubIds:_e,getAttachmentForUser:dt,markAttachmentMissing:ct,markAttachmentPresent:mt,setStarStatus:ht,setReadStatus:ft,addComment:bt,deleteComment:Rt,createDailyReport:Dt,updateDailyReport:async(r,a,o,c)=>{let b=await Te(e,r);if(!b.length||b[0].deletedAt)throw new Error("Not Found");if(b[0].userId!==a)throw new Error("Unauthorized");await e.transaction(async A=>{o.title!==void 0&&await Ne(A,r,{title:o.title,updatedAt:new Date,updatedBy:String(a)}),o.content!==void 0&&await je(A,r,{body:o.content,updatedAt:new Date,updatedBy:String(a)})}),h.invalidate(`daily-report:detail:${r}`),h.invalidatePrefix(`daily-report:detail:${r}:user:`),h.invalidatePrefix(v),await D(`${C}${r}`);let f=ee(I(b[0].businessDate,"YYYY-MM-DD"));f&&(h.invalidatePrefix(`daily-report:date:${f}:user:`),await D(`${R}${f}`));let S=await ge(r,a,{forceRefresh:!0});if(S){let A=await oe(),z=S.labels.some(j=>A.includes(j.id));await w(Ye.parse({type:"report-update",reportHubId:S.reportHubId,report:S,clientTempId:c,recipientRawUserId:z?a:void 0}),"updateDailyReport")}},publishDailyReport:async(r,a,o)=>{let c=await Te(e,r);if(!c.length)throw new Error("Not Found");if(c[0].userId!==a)throw new Error("Unauthorized");let b=await xe();if(!b)return null;if(await Ge(e,r,b),h.invalidatePrefix(`daily-report:detail:${r}:user:`),h.invalidatePrefix(v),h.invalidatePrefix(fe),await D(H),c[0].businessDate){let A=ee(I(c[0].businessDate,"YYYY-MM-DD"));A&&await D(`${R}${A}`)}let f=ee(I(c[0].businessDate,"YYYY-MM-DD"));f&&h.invalidate(`daily-report:date:${f}:user:${a}`);let S=await ge(r,a,{forceRefresh:!0});return S&&await w(Oe.parse({type:"report-publish",reportHubId:S.reportHubId,report:S,clientTempId:o}),"publishDailyReport"),S??null},deleteDailyReport:async(r,a,o)=>{let c=await Te(e,r);if(!c.length||c[0].deletedAt)throw new Error("Not Found");if(c[0].userId!==a)throw new Error("Unauthorized");if(await Ne(e,r,{deletedAt:new Date,deletedBy:String(a),updatedAt:new Date,updatedBy:String(a)}),h.invalidatePrefix(`daily-report:detail:${r}:user:`),h.invalidatePrefix(v),h.invalidatePrefix(fe),await D(H),c[0].businessDate){let b=ee(I(c[0].businessDate,"YYYY-MM-DD"));b&&await D(`${R}${b}`)}await w(qe.parse({type:"report-delete",reportHubId:r,clientTempId:o}),"deleteDailyReport")},findDailyReportHubById:Te,updateDailyReportHub:Ne,updateDailyReportInternal:je,deleteDailyReportLabel:Ge}}var Ie=require("drizzle-orm");function lt(t){let e=[],s=t&&t.length>0?t:[{key:"internal",name:"Internal",description:"Internal daily reports"},{key:"external",name:"External",description:"External daily reports"}];for(let i of s){let m=`daily_report_${i.key.toLowerCase().replace(/[^a-z0-9_]/g,"_")}`;e.push({resourceKey:m,name:i.name,description:i.description??`${i.name} daily report access`}),i.includeCommentResource!==!1&&e.push({resourceKey:`${m}_comment`,name:`${i.name} Comment`,description:`${i.name} daily report comment access`})}return e}async function tr(t,e,s){let i=t,y=e.TMResource,m=s.appKey,M=s.actor??"system:daily-report",h=new Date,O=s.resources??lt(s.sources);for(let u of O){let N=await i.select().from(y).where((0,Ie.and)((0,Ie.eq)(y.appKey,m),(0,Ie.eq)(y.resourceKey,u.resourceKey)));(!N||N.length===0)&&await i.insert(y).values({appKey:m,resourceKey:u.resourceKey,name:u.name,description:u.description??null,createdAt:h,createdBy:M,updatedAt:h,updatedBy:M})}}var rr=ne(1,"[DailyReportExternalSource]"),nr=(t,e,s,i=rr)=>{if(!t)return[];try{let y=JSON.parse(t);return Array.isArray(y)?y.map(s).filter(m=>m!==null):(i.warn(`Unexpected ${e} format: not an array`),[])}catch(y){return i.warn(`Failed to parse ${e}:`,y),[]}};var Se=require("drizzle-orm"),l=require("drizzle-orm/mssql-core");function ar(t,e){let s=(0,l.mssqlSchema)(t),i=e.userTable,y=s.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(Se.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:[i.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,Se.desc)(p.businessDate),(0,Se.desc)(p.id)),(0,l.index)(`${t}_DailyReportHub_deleted_at_index`).on(p.deletedAt)]),m=s.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:[y.id]})]),M=s.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:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportComment_user_id_fk`,columns:[p.userId],foreignColumns:[i.id]}),(0,l.index)(`${t}_DailyReportComment_hub_id_index`).on(p.hubId)]),h=s.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:[i.id]})]),O=s.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:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportHub_Label_label_id_fk`,columns:[p.labelId],foreignColumns:[h.id]})]),u=s.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:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportUserStatus_user_id_fk`,columns:[p.userId],foreignColumns:[i.id]})]),N=s.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:[y.id]}),(0,l.foreignKey)({name:`${t}_DailyReportAttachment_uploaded_by_fk`,columns:[p.uploadedBy],foreignColumns:[i.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:y,internal:m,comment:M,attachment:N,label:h,hubLabel:O,userStatus:u}}function sr(t){let e=$e(t.redis),s=new Re({defaultTtlMs:t.cacheDefaultTtlMs??6e4},e),i=Ke({...t,cache:s,epochs:e}),y=new De({redis:t.redis,streamKey:i.streamKey,cache:s,logger:t.logger}),m=ze({authenticate:t.authenticate,service:i,encodeUserId:t.encodeUserId,attachmentIdCodec:t.attachmentIdCodec,readAttachment:t.readAttachment,attachmentMaxBytes:t.attachmentMaxBytes,attachmentRateLimitPerMinute:t.attachmentRateLimitPerMinute,attachmentConcurrency:t.attachmentConcurrency,redis:t.redis,sseReader:y,streamKey:i.streamKey,loginRedirectPath:t.loginRedirectPath,enableDevCacheClear:t.enableDevCacheClear,logger:t.logger});return{service:i,cache:s,epochs:e,sseReader:y,streamKey:i.streamKey,...m}}0&&(module.exports={DailyReportSseReader,SqlResultCache,asciiFallbackFileName,createDailyReportHandlers,createDailyReportServer,createDailyReportService,createEpochStore,defineDailyReportAuthzResources,defineDailyReportSchema,encodeRfc8187,generateETag,isStreamIdLte,jsonResponseWithETag,sanitizeMediaType,seedDailyReportAuthzResources,transformJsonArray});
12
13
  //# sourceMappingURL=server.js.map