@@ -154,10 +154,9 @@ interface DashboardOrganizationSummaryInput {
154154}
155155
156156export function toDashboardProvisioning ( view : EnterpriseProvisioningView ) {
157- const { includedMonthlyCredits , usageLimitCredits, ...rest } = view
157+ const { usageLimitCredits, ...rest } = view
158158 return {
159159 ...rest ,
160- includedMonthlyDollars : creditsToDollars ( includedMonthlyCredits ) ,
161160 usageLimitDollars : creditsToDollars ( usageLimitCredits ) ,
162161 }
163162}
@@ -172,11 +171,7 @@ function buildDashboardOrganizationSummary({
172171} : DashboardOrganizationSummaryInput ) {
173172 const metadata = metadataRecord ( latestSubscription ?. metadata )
174173 const teamEconomics = getTeamOrganizationEconomics ( latestSubscription ?. plan , memberCount )
175- const includedMonthlyDollars =
176- teamEconomics ?. includedMonthlyDollars ??
177- creditsToDollars (
178- Math . max ( 0 , Math . round ( metadataNumber ( metadata , 'includedMonthlyCredits' ) ?? 0 ) )
179- )
174+ const planAllowanceDollars = teamEconomics ?. planAllowanceDollars ?? null
180175 const invoiceAmountCents = metadataNumber ( metadata , 'invoiceAmountCents' )
181176 const monthlyPrice = metadataNumber ( metadata , 'monthlyPrice' )
182177 const effectiveUsageLimitDollars = Number ( org . orgUsageLimit ?? 0 )
@@ -212,7 +207,7 @@ function buildDashboardOrganizationSummary({
212207 externalCollaboratorCount,
213208 seats,
214209 concurrencyLimit,
215- includedMonthlyDollars ,
210+ planAllowanceDollars ,
216211 usageLimitDollars,
217212 effectiveUsageLimitDollars,
218213 prepaidBalanceDollars : Number ( org . creditBalance ?? 0 ) ,
@@ -227,6 +222,27 @@ function buildDashboardOrganizationSummary({
227222 }
228223}
229224
225+ export function toDashboardConfigurationUpdate (
226+ intent : Awaited < ReturnType < typeof resolveEnterpriseMetadataIntent > > | null
227+ ) {
228+ const update = intent ?. configurationUpdate
229+ if ( ! update ) return null
230+ const metadata = update . requestedMetadata
231+ const usageLimitCredits = metadataNumber ( metadata , 'usageLimitCredits' )
232+ const seats = metadataNumber ( metadata , 'seats' )
233+ const concurrencyLimit = metadataNumber ( metadata , 'concurrencyLimit' )
234+
235+ return {
236+ id : update . id ,
237+ status : update . status ,
238+ requestedUsageLimitDollars :
239+ usageLimitCredits === null ? null : creditsToDollars ( usageLimitCredits ) ,
240+ requestedSeats : seats === null ? null : Math . round ( seats ) ,
241+ requestedConcurrencyLimit : concurrencyLimit === null ? null : Math . round ( concurrencyLimit ) ,
242+ error : update . error ,
243+ }
244+ }
245+
230246export async function listDashboardUsers ( { search, limit, offset } : PaginationInput ) {
231247 const trimmed = search . trim ( )
232248 // Mirror Better Auth's active-ban semantics: permanent bans and temporary
@@ -444,60 +460,65 @@ export async function listDashboardOrganizations({ search, limit, offset }: Pagi
444460export async function getDashboardOrganization ( organizationId : string ) {
445461 const summary = await getDashboardOrganizationSummary ( organizationId )
446462 if ( ! summary ) return null
447- const [ memberRows , externalRows , workspaceRows , limitRows ] = await Promise . all ( [
448- db
449- . select ( {
450- id : member . id ,
451- userId : user . id ,
452- name : user . name ,
453- email : user . email ,
454- role : member . role ,
455- } )
456- . from ( member )
457- . innerJoin ( user , eq ( user . id , member . userId ) )
458- . where ( eq ( member . organizationId , organizationId ) )
459- . orderBy ( user . name ) ,
460- db
461- . select ( {
462- userId : user . id ,
463- name : user . name ,
464- email : user . email ,
465- workspaceCount : countDistinct ( workspace . id ) ,
466- } )
467- . from ( permissions )
468- . innerJoin ( user , eq ( user . id , permissions . userId ) )
469- . innerJoin (
470- workspace ,
471- and (
472- eq ( permissions . entityType , 'workspace' ) ,
473- eq ( permissions . entityId , workspace . id ) ,
474- eq ( workspace . organizationId , organizationId )
463+ const { subscription : subscriptionRow , ...base } = summary
464+ const [ memberRows , externalRows , workspaceRows , limitRows , configurationIntent ] =
465+ await Promise . all ( [
466+ db
467+ . select ( {
468+ id : member . id ,
469+ userId : user . id ,
470+ name : user . name ,
471+ email : user . email ,
472+ role : member . role ,
473+ } )
474+ . from ( member )
475+ . innerJoin ( user , eq ( user . id , member . userId ) )
476+ . where ( eq ( member . organizationId , organizationId ) )
477+ . orderBy ( user . name ) ,
478+ db
479+ . select ( {
480+ userId : user . id ,
481+ name : user . name ,
482+ email : user . email ,
483+ workspaceCount : countDistinct ( workspace . id ) ,
484+ } )
485+ . from ( permissions )
486+ . innerJoin ( user , eq ( user . id , permissions . userId ) )
487+ . innerJoin (
488+ workspace ,
489+ and (
490+ eq ( permissions . entityType , 'workspace' ) ,
491+ eq ( permissions . entityId , workspace . id ) ,
492+ eq ( workspace . organizationId , organizationId )
493+ )
475494 )
476- )
477- . leftJoin (
478- member ,
479- and ( eq ( member . userId , permissions . userId ) , eq ( member . organizationId , organizationId ) )
480- )
481- . where ( and ( isNull ( member . id ) , isNull ( workspace . archivedAt ) ) )
482- . groupBy ( user . id , user . name , user . email )
483- . orderBy ( user . name ) ,
484- db
485- . select ( { id : workspace . id , name : workspace . name } )
486- . from ( workspace )
487- . where ( eq ( workspace . organizationId , organizationId ) )
488- . orderBy ( workspace . name ) ,
489- db
490- . select ( {
491- userId : organizationMemberUsageLimit . userId ,
492- limit : organizationMemberUsageLimit . usageLimit ,
493- } )
494- . from ( organizationMemberUsageLimit )
495- . where ( eq ( organizationMemberUsageLimit . organizationId , organizationId ) ) ,
496- ] )
495+ . leftJoin (
496+ member ,
497+ and ( eq ( member . userId , permissions . userId ) , eq ( member . organizationId , organizationId ) )
498+ )
499+ . where ( and ( isNull ( member . id ) , isNull ( workspace . archivedAt ) ) )
500+ . groupBy ( user . id , user . name , user . email )
501+ . orderBy ( user . name ) ,
502+ db
503+ . select ( { id : workspace . id , name : workspace . name } )
504+ . from ( workspace )
505+ . where ( eq ( workspace . organizationId , organizationId ) )
506+ . orderBy ( workspace . name ) ,
507+ db
508+ . select ( {
509+ userId : organizationMemberUsageLimit . userId ,
510+ limit : organizationMemberUsageLimit . usageLimit ,
511+ } )
512+ . from ( organizationMemberUsageLimit )
513+ . where ( eq ( organizationMemberUsageLimit . organizationId , organizationId ) ) ,
514+ subscriptionRow ?. plan === 'enterprise'
515+ ? resolveEnterpriseMetadataIntent ( db , subscriptionRow . id , subscriptionRow . metadata )
516+ : Promise . resolve ( null ) ,
517+ ] )
497518 const limits = new Map ( limitRows . map ( ( row ) => [ row . userId , Number ( row . limit ) ] ) )
498- const { subscription : subscriptionRow , ...base } = summary
499519 return {
500520 ...base ,
521+ configurationUpdate : toDashboardConfigurationUpdate ( configurationIntent ) ,
501522 members : memberRows . map ( ( row ) => ( {
502523 ...row ,
503524 usageLimitDollars : limits . get ( row . userId ) ?? null ,
@@ -570,7 +591,6 @@ export async function updateDashboardEnterpriseSeats(
570591export async function updateDashboardOrganizationLimits (
571592 organizationId : string ,
572593 values : {
573- includedMonthlyDollars ?: number
574594 usageLimitDollars ?: number
575595 concurrencyLimit ?: number | null
576596 } ,
@@ -597,9 +617,6 @@ export async function updateDashboardOrganizationLimits(
597617 . for ( 'update' )
598618 . limit ( 1 )
599619 const metadata = metadataRecord ( subscriptionRow ?. metadata )
600- if ( values . includedMonthlyDollars !== undefined && subscriptionRow ?. plan !== 'enterprise' ) {
601- throw new Error ( 'Included allowance is editable only for Enterprise organizations' )
602- }
603620 if ( values . concurrencyLimit !== undefined && subscriptionRow ?. plan !== 'enterprise' ) {
604621 throw new Error ( 'Concurrency is editable only for Enterprise organizations' )
605622 }
@@ -612,10 +629,6 @@ export async function updateDashboardOrganizationLimits(
612629 subscriptionId : subscriptionRow . id ,
613630 appliedMetadata : subscriptionRow . metadata ,
614631 buildDesiredMetadata : ( current ) => {
615- const included =
616- values . includedMonthlyDollars === undefined
617- ? Math . round ( metadataNumber ( current , 'includedMonthlyCredits' ) ?? 0 )
618- : dollarsToCredits ( values . includedMonthlyDollars )
619632 const configuredUsageLimit =
620633 values . usageLimitDollars === undefined
621634 ? Math . round (
@@ -625,7 +638,6 @@ export async function updateDashboardOrganizationLimits(
625638 : dollarsToCredits ( values . usageLimitDollars )
626639 return {
627640 ...current ,
628- includedMonthlyCredits : included ,
629641 usageLimitCredits : configuredUsageLimit ,
630642 ...( values . concurrencyLimit !== undefined
631643 ? { concurrencyLimit : values . concurrencyLimit }
@@ -644,18 +656,14 @@ export async function updateDashboardOrganizationLimits(
644656 subscriptionRow ?. plan ,
645657 memberCountRow ?. value ?? 0
646658 )
647- const included =
648- values . includedMonthlyDollars ??
649- ( teamEconomics
650- ? teamEconomics . includedMonthlyDollars
651- : creditsToDollars ( Math . round ( metadataNumber ( metadata , 'includedMonthlyCredits' ) ?? 0 ) ) )
659+ const planAllowance = teamEconomics ?. planAllowanceDollars ?? 0
652660 const prepaid = Number ( org . creditBalance )
653661 const configuredUsageLimit =
654662 values . usageLimitDollars ??
655663 ( metadataNumber ( metadata , 'usageLimitCredits' ) === null
656664 ? Number ( org . orgUsageLimit ?? 0 )
657665 : creditsToDollars ( metadataNumber ( metadata , 'usageLimitCredits' ) ?? 0 ) )
658- const effective = Math . max ( configuredUsageLimit , included + prepaid )
666+ const effective = Math . max ( configuredUsageLimit , planAllowance + prepaid )
659667 await tx
660668 . update ( organization )
661669 . set ( { orgUsageLimit : effective . toString ( ) , updatedAt : new Date ( ) } )
@@ -666,9 +674,6 @@ export async function updateDashboardOrganizationLimits(
666674 . set ( {
667675 metadata : {
668676 ...metadata ,
669- ...( subscriptionRow . plan === 'enterprise'
670- ? { includedMonthlyCredits : dollarsToCredits ( included ) }
671- : { } ) ,
672677 usageLimitCredits : dollarsToCredits ( configuredUsageLimit ) ,
673678 } ,
674679 } )
@@ -731,16 +736,7 @@ export async function grantDashboardOrganizationBalance(
731736 subscriptionRow ?. plan ,
732737 memberCountRow ?. value ?? 0
733738 )
734- const includedDollars = teamEconomics
735- ? teamEconomics . includedMonthlyDollars
736- : creditsToDollars (
737- Math . round (
738- metadataNumber (
739- metadataRecord ( subscriptionRow ?. metadata ) ,
740- 'includedMonthlyCredits'
741- ) ?? 0
742- )
743- )
739+ const planAllowanceDollars = teamEconomics ?. planAllowanceDollars ?? 0
744740 const subscriptionMetadata = metadataRecord ( subscriptionRow ?. metadata )
745741 const configuredUsageLimitCredits = metadataNumber (
746742 subscriptionMetadata ,
@@ -753,7 +749,7 @@ export async function grantDashboardOrganizationBalance(
753749 const grantDollarDelta = toDecimal ( amountDollars ) . toString ( )
754750 const usageLimitFallback = getOrganizationUsageLimitFallbackDollars ( {
755751 creditBalanceDollarsBeforeGrant : org . creditBalance ,
756- includedDollars ,
752+ planAllowanceDollars ,
757753 configuredUsageLimitDollars,
758754 } )
759755 const [ updated ] = await tx
0 commit comments