@@ -11,12 +11,14 @@ import * as Dz from "drizzle-orm";
1111import { Effect , Option } from "effect" ;
1212import { Database , type DatabaseError } from "../Database.ts" ;
1313import { FoldersPolicy } from "./FoldersPolicy.ts" ;
14+ import { FoldersRepo } from "./FoldersRepo.ts" ;
1415
1516// @effect -diagnostics-next-line leakingRequirements:off
1617export class Folders extends Effect . Service < Folders > ( ) ( "Folders" , {
1718 effect : Effect . gen ( function * ( ) {
1819 const db = yield * Database ;
1920 const policy = yield * FoldersPolicy ;
21+ const repo = yield * FoldersRepo ;
2022
2123 const deleteFolder = ( folder : {
2224 id : Folder . FolderId ;
@@ -78,45 +80,33 @@ export class Folders extends Effect.Service<Folders>()("Folders", {
7880
7981 if ( Option . isSome ( data . parentId ) ) {
8082 const parentId = data . parentId . value ;
81- const [ parentFolder ] = yield * db . execute ( ( db ) =>
82- db
83- . select ( )
84- . from ( Db . folders )
85- . where (
86- Dz . and (
87- Dz . eq ( Db . folders . id , parentId ) ,
88- Dz . eq ( Db . folders . organizationId , user . activeOrganizationId ) ,
83+
84+ yield * repo
85+ . getById ( parentId , {
86+ organizationId : Organisation . OrganisationId . make (
87+ user . activeOrganizationId ,
88+ ) ,
89+ } )
90+ . pipe (
91+ Policy . withPolicy ( policy . canEdit ( parentId ) ) ,
92+ Effect . flatMap (
93+ Effect . catchTag (
94+ "NoSuchElementException" ,
95+ ( ) => new Folder . NotFoundError ( ) ,
8996 ) ,
9097 ) ,
91- ) ;
92-
93- if ( ! parentFolder ) return yield * new Folder . NotFoundError ( ) ;
98+ ) ;
9499 }
95100
96- const folder = {
97- id : Folder . FolderId . make ( nanoId ( ) ) ,
101+ yield * repo . create ( {
98102 name : data . name ,
99103 color : data . color ,
100- organizationId : user . activeOrganizationId ,
101- createdById : user . id ,
102- spaceId : data . spaceId ,
103- parentId : data . parentId ,
104- } ;
105-
106- yield * db . execute ( ( db ) =>
107- db . insert ( Db . folders ) . values ( {
108- ...folder ,
109- spaceId : Option . getOrNull ( folder . spaceId ) ,
110- parentId : Option . getOrNull ( folder . parentId ) ,
111- } ) ,
112- ) ;
113-
114- return new Folder . Folder ( {
115- ...folder ,
116104 organizationId : Organisation . OrganisationId . make (
117105 user . activeOrganizationId ,
118106 ) ,
119107 createdById : User . UserId . make ( user . id ) ,
108+ spaceId : data . spaceId ,
109+ parentId : data . parentId ,
120110 } ) ;
121111 } ) ,
122112
@@ -140,12 +130,17 @@ export class Folders extends Effect.Service<Folders>()("Folders", {
140130 folderId : Folder . FolderId ,
141131 data : Folder . FolderUpdate ,
142132 ) {
143- const [ folder ] = yield * db
144- . execute ( ( db ) =>
145- db . select ( ) . from ( Db . folders ) . where ( Dz . eq ( Db . folders . id , folderId ) ) ,
146- )
147- . pipe ( Policy . withPolicy ( policy . canEdit ( folderId ) ) ) ;
148- if ( ! folder ) return yield * new Folder . NotFoundError ( ) ;
133+ const folder = yield * repo
134+ . getById ( folderId )
135+ . pipe (
136+ Policy . withPolicy ( policy . canEdit ( folderId ) ) ,
137+ Effect . flatMap (
138+ Effect . catchTag (
139+ "NoSuchElementException" ,
140+ ( ) => new Folder . NotFoundError ( ) ,
141+ ) ,
142+ ) ,
143+ ) ;
149144
150145 // If parentId is provided and not null, verify it exists and belongs to the same organization
151146 if ( ! data . parentId ) return ;
@@ -155,20 +150,21 @@ export class Folders extends Effect.Service<Folders>()("Folders", {
155150 if ( parentId === folderId )
156151 return yield * new Folder . RecursiveDefinitionError ( ) ;
157152
158- const [ parentFolder ] = yield * db
159- . execute ( ( db ) =>
160- db
161- . select ( )
162- . from ( Db . folders )
163- . where (
164- Dz . and (
165- Dz . eq ( Db . folders . id , parentId ) ,
166- Dz . eq ( Db . folders . organizationId , folder . organizationId ) ,
167- ) ,
153+ const parentFolder = yield * repo
154+ . getById ( parentId , {
155+ organizationId : Organisation . OrganisationId . make (
156+ folder . organizationId ,
157+ ) ,
158+ } )
159+ . pipe (
160+ Policy . withPolicy ( policy . canEdit ( parentId ) ) ,
161+ Effect . flatMap (
162+ Effect . catchTag (
163+ "NoSuchElementException" ,
164+ ( ) => new Folder . ParentNotFoundError ( ) ,
168165 ) ,
169- )
170- . pipe ( Policy . withPolicy ( policy . canEdit ( parentId ) ) ) ;
171- if ( ! parentFolder ) return yield * new Folder . ParentNotFoundError ( ) ;
166+ ) ,
167+ ) ;
172168
173169 // Check for circular references in the folder hierarchy
174170 let currentParentId = parentFolder . parentId ;
@@ -177,21 +173,14 @@ export class Folders extends Effect.Service<Folders>()("Folders", {
177173 return yield * new Folder . RecursiveDefinitionError ( ) ;
178174
179175 const parentId = currentParentId ;
180- const [ nextParent ] = yield * db . execute ( ( db ) =>
181- db
182- . select ( )
183- . from ( Db . folders )
184- . where (
185- Dz . and (
186- Dz . eq ( Db . folders . id , parentId ) ,
187- // This should be implied but extra tenant isolation can't hurt
188- Dz . eq ( Db . folders . organizationId , folder . organizationId ) ,
189- ) ,
190- ) ,
191- ) ;
192-
193- if ( ! nextParent ) break ;
194- currentParentId = nextParent . parentId ;
176+ const nextParent = yield * repo . getById ( parentId , {
177+ organizationId : Organisation . OrganisationId . make (
178+ folder . organizationId ,
179+ ) ,
180+ } ) ;
181+
182+ if ( Option . isNone ( nextParent ) ) break ;
183+ currentParentId = nextParent . value . parentId ;
195184 }
196185
197186 yield * db . execute ( ( db ) =>
0 commit comments