@@ -6,7 +6,18 @@ import type { AppFlags } from "./config";
66import type { IFeaturesRepository } from "./features.repository.interface" ;
77import { getFeatureFlag } from "./server/utils" ;
88
9+ /**
10+ * Repository class for managing feature flags and feature access control.
11+ * Implements the IFeaturesRepository interface to provide feature flag functionality
12+ * for users, teams, and global application features.
13+ */
914export class FeaturesRepository implements IFeaturesRepository {
15+ /**
16+ * Checks if a feature is enabled globally in the application.
17+ * @param slug - The feature flag identifier to check
18+ * @returns Promise<boolean> - True if the feature is enabled globally, false otherwise
19+ * @throws Error if the feature flag check fails
20+ */
1021 async checkIfFeatureIsEnabledGlobally ( slug : keyof AppFlags ) {
1122 try {
1223 return await getFeatureFlag ( db , slug ) ;
@@ -15,6 +26,15 @@ export class FeaturesRepository implements IFeaturesRepository {
1526 throw err ;
1627 }
1728 }
29+
30+ /**
31+ * Checks if a specific user has access to a feature.
32+ * Checks both direct user feature assignments and team-based feature access.
33+ * @param userId - The ID of the user to check
34+ * @param slug - The feature identifier to check
35+ * @returns Promise<boolean> - True if the user has access to the feature, false otherwise
36+ * @throws Error if the feature access check fails
37+ */
1838 async checkIfUserHasFeature ( userId : number , slug : string ) {
1939 try {
2040 /**
@@ -39,6 +59,15 @@ export class FeaturesRepository implements IFeaturesRepository {
3959 throw err ;
4060 }
4161 }
62+
63+ /**
64+ * Private helper method to check if a user belongs to any team that has access to a feature.
65+ * @param userId - The ID of the user to check
66+ * @param slug - The feature identifier to check
67+ * @returns Promise<boolean> - True if the user belongs to a team with the feature, false otherwise
68+ * @throws Error if the team feature check fails
69+ * @private
70+ */
4271 private async checkIfUserBelongsToTeamWithFeature ( userId : number , slug : string ) {
4372 try {
4473 const user = await db . user . findUnique ( {
@@ -65,10 +94,34 @@ export class FeaturesRepository implements IFeaturesRepository {
6594 throw err ;
6695 }
6796 }
97+
98+ /**
99+ * Checks if a team has access to a specific feature.
100+ * Also checks if the team's parent organization has the feature.
101+ * @param teamId - The ID of the team to check
102+ * @param featureId - The feature identifier to check
103+ * @returns Promise<boolean> - True if the team has access to the feature, false otherwise
104+ * @throws Error if the team feature check fails
105+ */
68106 async checkIfTeamHasFeature ( teamId : number , featureId : keyof AppFlags ) {
69107 try {
70- const teamFeature = await db . teamFeatures . findUnique ( {
71- where : { teamId_featureId : { teamId, featureId } } ,
108+ const teamFeature = await db . teamFeatures . findFirst ( {
109+ where : {
110+ OR : [
111+ { teamId, featureId } ,
112+ {
113+ team : {
114+ parent : {
115+ features : {
116+ some : {
117+ featureId,
118+ } ,
119+ } ,
120+ } ,
121+ } ,
122+ } ,
123+ ] ,
124+ } ,
72125 } ) ;
73126 return ! ! teamFeature ;
74127 } catch ( err ) {
0 commit comments