Skip to content

Commit

Permalink
feat: Reworked the project structure to make it easier and more maint…
Browse files Browse the repository at this point in the history
…ainable, along with the structure change theres README files to document the folders.
  • Loading branch information
AlexMachin1997 committed Oct 29, 2024
1 parent 32651c9 commit bf819ca
Show file tree
Hide file tree
Showing 104 changed files with 1,501 additions and 780 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json",
"prepare": "husky install",
"gql-to-interfaces": "cd ./src && ts-node schema-to-typings"
"gql-to-interfaces": "cd ./src/scripts && ts-node schema-to-typings.ts"
},
"dependencies": {
"@apollo/server": "^4.10.4",
Expand Down
56 changes: 10 additions & 46 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,19 @@
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import joi from 'joi';

import { DiscoverFilteringModule } from './discover-filtering/discover-filtering.module';
import { DiscoverFormDataModule } from './discover-form-data/discover-form-data.module';
import { FilteringOptionsModule } from './filtering-options/filtering-options.module';
import { MovieModule } from './movie/movie.module';
import { PersonModule } from './person/person.module';
import { ShowModule } from './show/show.module';
import { graphqlConfig } from './config/graphql.config';
import { serviceConfig } from './config/service.config';
import { DiscoverFilteringModule } from './modules/discover/filtering/discover-filtering.module';
import { DiscoverFormDataModule } from './modules/discover/form-data/discover-form-data.module';
import { FilteringOptionsModule } from './modules/discover/options/filtering-options.module';
import { MovieModule } from './modules/movies/movie.module';
import { PersonModule } from './modules/person/person.module';
import { ShowModule } from './modules/shows/show.module';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
validationSchema: joi.object({
THE_OPEN_MOVIE_DATABASE_API_KEY: joi.string().required()
})
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
playground: true,
serviceConfig,
graphqlConfig,

// Must start with ./src/ for some reason otherwise nestjs doesn't pick up the files grr
typePaths: [
// Enums used by all the graphql schemas
'./src/models/enum.graphql',
'./src/models/Pagination.graphql',

// Entertainment specific models, used for the Movie and Show schemas
'./src/models/entertainment/BelongsToCollection.graphql',
'./src/models/entertainment/Cast.graphql',
'./src/models/entertainment/Company.graphql',
'./src/models/entertainment/Crew.graphql',
'./src/models/entertainment/Genre.graphql',
'./src/models/entertainment/Keyword.graphql',
'./src/models/entertainment/Recommendation.graphql',
'./src/models/entertainment/Review.graphql',
'./src/models/entertainment/Social.graphql',
'./src/models/entertainment/Video.graphql',
'./src/models/Discover.graphql',

// Individual resource schemas
'./src/models/Show.graphql',
'./src/models/Movie.graphql',
'./src/models/Person.graphql',

'./src/models/Query.graphql'
]
}),
ShowModule,
MovieModule,
PersonModule,
Expand Down
36 changes: 36 additions & 0 deletions src/common/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Common Directory

The Common directory is dedicated to shared code that is specific to the application's business logic and domain models, but needs to be reused across multiple features. Unlike core utilities, items in Common are tied to the application's domain concepts.

## Purpose

- Houses shared business logic and domain-specific utilities
- Provides reusable components that implement business rules
- Contains shared types and interfaces related to domain models
- Centralizes common validation logic and business constraints

## Examples of What Goes Here

1. Shared business validation rules
2. Common domain model transformations
3. Business-specific utility functions
4. Shared domain interfaces and types
5. Common business calculations or formulas

## When to Use Common

Use the Common directory when:

- The code implements business rules needed by multiple features
- You have domain-specific logic that's reused across different modules
- You need to share business validation or transformation logic
- Multiple features need access to the same domain-specific utilities

## When Not to Use Common

Don't use Common for:

- Generic utility functions (use Core instead)
- Framework-specific code
- Infrastructure concerns
- Pure technical utilities with no business logic
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
48 changes: 48 additions & 0 deletions src/config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Config Directory

The Config directory contains application-wide configuration settings, environment variables, and setup code that defines how the application behaves in different environments.

## Purpose

- Centralizes all configuration-related code and settings
- Manages environment-specific variables and settings
- Defines application-wide setup and initialization
- Houses configuration interfaces and types
- Provides configuration factories and providers

## What Goes Here

1. Environment configuration files
2. Service configuration providers
3. Module configuration factories
4. GraphQL and API configurations
5. Type generation configurations
6. Path and file location configurations
7. Global application settings

## When to Use Config

Use the Config directory when:

- Adding new application-wide settings
- Defining environment-specific configurations
- Setting up module or service configurations
- Managing external service connections
- Defining global type generation settings

## When Not to Use Config

Don't use Config for:

- Feature-specific settings (belong in respective modules)
- Business logic or rules
- Utility functions
- Runtime data management
- Local component configurations

## Current Configuration Files

- `graphql.config.ts` - GraphQL module configuration
- `service.config.ts` - Core service settings
- `filePaths.ts` - GraphQL schema file path management
- `schemaToTypings.ts` - TypeScript definitions generation config
76 changes: 76 additions & 0 deletions src/config/filePaths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { join } from 'path';

const GRAPHQL_BASE_PATH = 'graphql';
/**
* Gets the GraphQL schema file paths in either absolute or relative format
*
* Two different path formats are needed for different use cases:
*
* 1. Absolute paths (starting with 'src/'):
* - Required by NestJS GraphQL module to properly load schema files
* - Used in app.module.ts via graphql.config.ts for runtime schema loading
* - The NestJS GraphQL module specifically requires paths to start with 'src/'
* to properly resolve and watch schema files during development
* - Example: 'src/graphql/models/Query.graphql'
*
* 2. Relative paths (from project root):
* - Required by GraphQLDefinitionsFactory for TypeScript interface generation
* - Used in schema-to-typings.ts which runs as a separate process outside NestJS
* - Since this runs as a separate script, it needs full filesystem paths relative
* to the project root to locate the schema files
* - Example: '/path/to/project/graphql/models/Query.graphql'
*
* This dual path handling ensures both:
* - Runtime schema loading works correctly in the NestJS application
* - Type generation script can find and process schema files from the command line
*
* @param pathType - Whether to return absolute or relative paths
* @returns Array of GraphQL schema file paths in the requested format
*/
export function getGraphQLPaths(pathType: 'absolute' | 'relative' = 'absolute') {
const graphqlPaths = [
// Enums used by all the graphql schemas
'models/Common/CommonEnums.graphql',
'models/Common/CommonPagination.graphql',

// Entertainment specific models
'models/Entertainment/BelongsToCollection.graphql',
'models/Entertainment/Cast.graphql',
'models/Entertainment/Company.graphql',
'models/Entertainment/Crew.graphql',
'models/Entertainment/Genre.graphql',
'models/Entertainment/Keyword.graphql',
'models/Entertainment/Recommendation.graphql',
'models/Entertainment/Review.graphql',
'models/Entertainment/Social.graphql',
'models/Entertainment/Video.graphql',

// Discover specific models
'models/Discover/RangeFilters.graphql',
'models/Discover/FiltersInput.graphql',
'models/Discover.graphql',
'models/Discover/DiscoverResult.graphql',
'models/Discover/FiltersFormData.graphql',

// Person specific models
'models/Person/CreditGroup.graphql',
'models/Person/Credit.graphql',
'models/Person/Person.graphql',

// Individual resource schemas
'models/Show/Show.graphql',
'models/Movie/Movie.graphql',
'models/Person/Person.graphql',

'models/Query.graphql'
];

if (pathType === 'absolute') {
// For NestJS GraphQL module (absolute paths starting with src/)
return graphqlPaths.map((path) => `src/${GRAPHQL_BASE_PATH}/${path}`);
}

// For GraphQLDefinitionsFactory (relative paths from project root)
return graphqlPaths.map((path) => join(process.cwd(), `../${GRAPHQL_BASE_PATH}/${path}`));
}
12 changes: 12 additions & 0 deletions src/config/graphql.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ApolloDriverConfig, ApolloDriver } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';

import { getGraphQLPaths } from './filePaths';

export const graphqlConfig = GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
playground: true,

// Must start with src/ for some reason otherwise nestjs doesn't pick up the files grr
typePaths: getGraphQLPaths('absolute')
});
Loading

0 comments on commit bf819ca

Please sign in to comment.