diff --git a/.gitignore b/.gitignore index 2709a60..4b56acf 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,3 @@ pids # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Database -common-cents.db \ No newline at end of file diff --git a/bruno/Common Cents/Categories/folder.bru b/bruno/Common Cents/Categories/folder.bru index ae65a21..c32401e 100644 --- a/bruno/Common Cents/Categories/folder.bru +++ b/bruno/Common Cents/Categories/folder.bru @@ -1,6 +1,5 @@ meta { name: Categories - seq: 2 } auth { diff --git a/bruno/Common Cents/Expenses/LOC DEL Expense.bru b/bruno/Common Cents/Expenses/LOC DEL Expense.bru new file mode 100644 index 0000000..dfb6024 --- /dev/null +++ b/bruno/Common Cents/Expenses/LOC DEL Expense.bru @@ -0,0 +1,11 @@ +meta { + name: LOC DEL Expense + type: http + seq: 3 +} + +delete { + url: {{localBaseUrl}}/expenses/2aa94170-2c57-4c4f-a1e7-13544ba72917 + body: none + auth: inherit +} diff --git a/bruno/Common Cents/Expenses/LOC DELETE Expense.bru b/bruno/Common Cents/Expenses/LOC DELETE Expense.bru deleted file mode 100644 index 6725687..0000000 --- a/bruno/Common Cents/Expenses/LOC DELETE Expense.bru +++ /dev/null @@ -1,15 +0,0 @@ -meta { - name: LOC DELETE Expense - type: http - seq: 5 -} - -delete { - url: {{localBaseUrl}}/{{resourcePath}}/{{resourceId}} - body: none - auth: inherit -} - -vars:pre-request { - resourceId: 41294f87-ab77-4fdd-9509-6968e6533962 -} diff --git a/bruno/Common Cents/Expenses/LOC GET Expense By ID.bru b/bruno/Common Cents/Expenses/LOC GET Expense By ID.bru index c591a98..935e4ee 100644 --- a/bruno/Common Cents/Expenses/LOC GET Expense By ID.bru +++ b/bruno/Common Cents/Expenses/LOC GET Expense By ID.bru @@ -5,11 +5,7 @@ meta { } get { - url: {{localBaseUrl}}/{{resourcePath}}/{{resourceId}} + url: {{localBaseUrl}}/expenses/2aa94170-2c57-4c4f-a1e7-13544ba72917 body: none auth: inherit } - -vars:pre-request { - resourceId: 1d6d2842-b271-489b-bd93-e3ceaee5a139 -} diff --git a/bruno/Common Cents/Expenses/LOC GET Expenses.bru b/bruno/Common Cents/Expenses/LOC GET Expenses.bru index 17a85b6..b2e8e2c 100644 --- a/bruno/Common Cents/Expenses/LOC GET Expenses.bru +++ b/bruno/Common Cents/Expenses/LOC GET Expenses.bru @@ -5,7 +5,7 @@ meta { } get { - url: {{localBaseUrl}}/{{resourcePath}} + url: {{localBaseUrl}}/expenses body: none auth: inherit } diff --git a/bruno/Common Cents/Expenses/LOC PATCH Expense Full.bru b/bruno/Common Cents/Expenses/LOC PATCH Expense Full.bru new file mode 100644 index 0000000..e9a5f02 --- /dev/null +++ b/bruno/Common Cents/Expenses/LOC PATCH Expense Full.bru @@ -0,0 +1,23 @@ +meta { + name: LOC PATCH Expense Full + type: http + seq: 6 +} + +patch { + url: {{localBaseUrl}}/expenses/0708e7f7-3a2a-4b93-81da-38954925ca78 + body: json + auth: inherit +} + +body:json { + { + "date": "2025-12-15", + "cents": 888, + "categoryId": "1", + "merchantId": "1", + "subcategoryIds": ["2"], + "tagIds": ["2"], + "description": "PATCHED Desc." + } +} diff --git a/bruno/Common Cents/Expenses/LOC POST Expense Full.bru b/bruno/Common Cents/Expenses/LOC POST Expense Full.bru new file mode 100644 index 0000000..d0e6451 --- /dev/null +++ b/bruno/Common Cents/Expenses/LOC POST Expense Full.bru @@ -0,0 +1,23 @@ +meta { + name: LOC POST Expense Full + type: http + seq: 4 +} + +post { + url: {{localBaseUrl}}/expenses + body: json + auth: inherit +} + +body:json { + { + "date": "2025-12-01", + "cents": 987, + "categoryId": "1", + "merchantId": "1", + "subcategoryIds": ["1","2"], + "tagIds": ["1","2"], + "description": "NEW FULL expense" + } +} diff --git a/bruno/Common Cents/Expenses/LOC POST Expense Partial.bru b/bruno/Common Cents/Expenses/LOC POST Expense Partial.bru new file mode 100644 index 0000000..bfc7302 --- /dev/null +++ b/bruno/Common Cents/Expenses/LOC POST Expense Partial.bru @@ -0,0 +1,20 @@ +meta { + name: LOC POST Expense Partial + type: http + seq: 5 +} + +post { + url: {{localBaseUrl}}/expenses + body: json + auth: inherit +} + +body:json { + { + "date": "2025-12-01", + "cents": 987, + "categoryId": "1", + "description": "NEW PARTIAL expense" + } +} diff --git a/bruno/Common Cents/Expenses/LOC POST Expense.bru b/bruno/Common Cents/Expenses/LOC POST Expense.bru deleted file mode 100644 index a458095..0000000 --- a/bruno/Common Cents/Expenses/LOC POST Expense.bru +++ /dev/null @@ -1,38 +0,0 @@ -meta { - name: LOC POST Expense - type: http - seq: 3 -} - -post { - url: {{localBaseUrl}}/{{resourcePath}} - body: json - auth: inherit -} - -body:json { - { - "year": "2026", - "month": "01", - "day": "02", - "cents": 1000, - "description": "With cat, subcat and merchant and two tags", - "category": { - "id": "a73fbfdd-1949-4be9-8cdc-ea9197b9b8b6" - }, - "subCategory": { - "id": "270ceaea-9cb8-4c6a-846f-ea35ed4d12f7" - }, - "merchant": { - "id": "61246db4-3110-4fe2-bdab-d819b8fd0705" - }, - "tags": [ - { - "id": "2616f724-f3ce-46df-8b30-897f147f6b74" - }, - { - "id": "16ed84e0-2d17-45c7-ada8-6fe7f8cc8720" - } - ] - } -} diff --git a/bruno/Common Cents/Expenses/LOC PUT Expense.bru b/bruno/Common Cents/Expenses/LOC PUT Expense.bru deleted file mode 100644 index 7042846..0000000 --- a/bruno/Common Cents/Expenses/LOC PUT Expense.bru +++ /dev/null @@ -1,21 +0,0 @@ -meta { - name: LOC PUT Expense - type: http - seq: 4 -} - -put { - url: {{localBaseUrl}}/{{resourcePath}} - body: json - auth: inherit -} - -body:json { - { - "id": "0254a07d-9dfa-4c06-b7b3-48d30efff991", - "description": "Cat, no sub-cat or merchant", - "category": { - "id": "db434e98-5f32-4202-b69c-eb7d1d248b3e" - } - } -} diff --git a/bruno/Common Cents/Expenses/folder.bru b/bruno/Common Cents/Expenses/folder.bru index 5e0ac02..9a3fbf0 100644 --- a/bruno/Common Cents/Expenses/folder.bru +++ b/bruno/Common Cents/Expenses/folder.bru @@ -1,11 +1,4 @@ meta { name: Expenses -} - -auth { - mode: inherit -} - -vars:pre-request { - resourcePath: expenses + seq: 2 } diff --git a/bruno/Common Cents/Merchants/folder.bru b/bruno/Common Cents/Merchants/folder.bru index dc13882..2ffb460 100644 --- a/bruno/Common Cents/Merchants/folder.bru +++ b/bruno/Common Cents/Merchants/folder.bru @@ -1,6 +1,5 @@ meta { name: Merchants - seq: 3 } auth { diff --git a/bruno/Common Cents/Sub-categories/folder.bru b/bruno/Common Cents/Sub-categories/folder.bru index 47ece91..a7f720c 100644 --- a/bruno/Common Cents/Sub-categories/folder.bru +++ b/bruno/Common Cents/Sub-categories/folder.bru @@ -1,6 +1,5 @@ meta { name: Sub-categories - seq: 4 } auth { diff --git a/bruno/Common Cents/Tags/folder.bru b/bruno/Common Cents/Tags/folder.bru index ba06b7e..aa07bea 100644 --- a/bruno/Common Cents/Tags/folder.bru +++ b/bruno/Common Cents/Tags/folder.bru @@ -1,6 +1,5 @@ meta { name: Tags - seq: 5 } auth { diff --git a/common-cents.db b/common-cents.db new file mode 100644 index 0000000..656df02 Binary files /dev/null and b/common-cents.db differ diff --git a/src/app.module.ts b/src/app.module.ts index d831a58..fd2edf1 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -9,14 +9,12 @@ import { CategoriesModule } from './categories/categories.module'; import { Category } from './categories/entities/category.entity'; import { SubCategoriesModule } from './sub-categories/sub-categories.module'; import { SubCategory } from './sub-categories/entities/sub-category.entity'; -import { ExpensesModule } from './expenses/expenses.module'; -import { Expense } from './expenses/entities/expense.entity'; const sqliteConfig: TypeOrmModuleOptions = { synchronize: true, // typeorm -h (schema:sync) type: 'sqlite', database: 'common-cents.db', - entities: [Merchant, Tag, Category, SubCategory, Expense] + entities: [Merchant, Tag, Category, SubCategory] } @Module({ @@ -25,8 +23,7 @@ const sqliteConfig: TypeOrmModuleOptions = { MerchantsModule, TagsModule, CategoriesModule, - SubCategoriesModule, - ExpensesModule + SubCategoriesModule ], controllers: [AppController], providers: [] diff --git a/src/categories/entities/category.entity.ts b/src/categories/entities/category.entity.ts index 806866f..25ee60c 100644 --- a/src/categories/entities/category.entity.ts +++ b/src/categories/entities/category.entity.ts @@ -5,6 +5,6 @@ export class Category { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ unique: true }) + @Column() name: string; } diff --git a/src/expenses/dto/create-expense.dto.ts b/src/expenses/dto/create-expense.dto.ts deleted file mode 100644 index 52a8f38..0000000 --- a/src/expenses/dto/create-expense.dto.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Category } from '../../categories/entities/category.entity'; - -export class CreateExpenseDto { - year: string; - month: string; - day: string; - cents: number; - description: string; - category: Category -} diff --git a/src/expenses/dto/update-expense.dto.ts b/src/expenses/dto/update-expense.dto.ts deleted file mode 100644 index e5be379..0000000 --- a/src/expenses/dto/update-expense.dto.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PartialType } from '@nestjs/mapped-types'; -import { CreateExpenseDto } from './create-expense.dto'; - -export class UpdateExpenseDto extends PartialType(CreateExpenseDto) { - id: string; -} diff --git a/src/expenses/entities/expense.entity.ts b/src/expenses/entities/expense.entity.ts deleted file mode 100644 index 36a116d..0000000 --- a/src/expenses/entities/expense.entity.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Column, Entity, JoinTable, ManyToMany, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'; -import { Tag } from '../../tags/entities/tag.entity'; -import { SubCategory } from '../../sub-categories/entities/sub-category.entity'; -import { Category } from '../../categories/entities/category.entity'; -import { Merchant } from '../../merchants/entities/merchant.entity'; - -@Entity() -export class Expense { - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column() - year: string; - - @Column() - month: string; - - @Column() - day: string; - - @Column() - cents: number; - - @Column({ nullable: true }) - description: string; - - @ManyToOne(() => Category, { eager: true }) - category: Category; - - @ManyToOne(() => SubCategory, { nullable: true, eager: true }) - subCategory: SubCategory; - - @ManyToOne(() => Merchant, { nullable: true, eager: true }) - merchant: Merchant; - - @ManyToMany(() => Tag, { nullable: true, eager: true }) - @JoinTable() - tags: Tag[]; -} diff --git a/src/expenses/expense-data.service.ts b/src/expenses/expense-data.service.ts deleted file mode 100644 index ceff180..0000000 --- a/src/expenses/expense-data.service.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { DataSource, Repository } from 'typeorm'; -import { Expense } from './entities/expense.entity'; -import { UpdateExpenseDto } from './dto/update-expense.dto'; -import { CreateExpenseDto } from './dto/create-expense.dto'; - -@Injectable() -export class ExpenseDataService { - private expenses: Repository; - - public constructor(private dataSource: DataSource) { - this.expenses = this.dataSource.getRepository(Expense); - } - - public async getAll(): Promise { - return await this.expenses.find(); - } - - public async getById(id: string): Promise { - return await this.expenses.findOneBy({ id }); - } - - public async create(expense: CreateExpenseDto): Promise { - return await this.expenses.save(expense); - } - - public async update(expense: UpdateExpenseDto): Promise { - return await this.expenses.save(expense); - } - - public async delete(id: string): Promise { - await this.expenses.delete({ id }); - } -} diff --git a/src/expenses/expenses.controller.ts b/src/expenses/expenses.controller.ts deleted file mode 100644 index 98350b9..0000000 --- a/src/expenses/expenses.controller.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - Controller, - Get, - Post, - Put, - Delete, - Body, - Param, - HttpCode, - HttpStatus, - BadRequestException, - NotFoundException, - InternalServerErrorException -} from '@nestjs/common'; -import { ExpensesService } from './expenses.service'; -import { CreateExpenseDto } from './dto/create-expense.dto'; -import { UpdateExpenseDto } from './dto/update-expense.dto'; -import { Expense } from './entities/expense.entity'; - -@Controller('expenses') -export class ExpensesController { - constructor(private readonly expensesService: ExpensesService) { } - - @Get() - @HttpCode(HttpStatus.OK) - public async findAll(): Promise { - return await this.expensesService.findAll(); - } - - @Get(':id') - @HttpCode(HttpStatus.OK) - public async findOne(@Param('id') id: string): Promise { - if (!id) { - throw new BadRequestException('No ID provided.'); - } - - try { - return await this.expensesService.findById(id); - } - catch (error) { - throw new NotFoundException(error); - } - } - - @Post() - @HttpCode(HttpStatus.CREATED) - public async create(@Body() expense: CreateExpenseDto): Promise { - if (!expense) { - throw new BadRequestException('Expense name cannot be empty.'); - } - - try { - return await this.expensesService.create(expense); - } - catch (error) { - throw new InternalServerErrorException(error); - } - } - - @Put() - @HttpCode(HttpStatus.OK) - public async update(@Body() expense: UpdateExpenseDto): Promise { - if (!expense.id) { - throw new BadRequestException('Expense ID cannot be empty.'); - } - - return await this.expensesService.update(expense); - } - - @Delete(':id') - @HttpCode(HttpStatus.NO_CONTENT) - public async remove(@Param('id') id: string): Promise { - return await this.expensesService.remove(id); - } -} diff --git a/src/expenses/expenses.module.ts b/src/expenses/expenses.module.ts deleted file mode 100644 index 2179916..0000000 --- a/src/expenses/expenses.module.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ExpensesService } from './expenses.service'; -import { ExpensesController } from './expenses.controller'; -import { ExpenseDataService } from './expense-data.service'; - -@Module({ - controllers: [ExpensesController], - providers: [ExpensesService, ExpenseDataService], -}) -export class ExpensesModule { } diff --git a/src/expenses/expenses.service.ts b/src/expenses/expenses.service.ts deleted file mode 100644 index 4e822e6..0000000 --- a/src/expenses/expenses.service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Injectable } from '@nestjs/common'; -import { CreateExpenseDto } from './dto/create-expense.dto'; -import { UpdateExpenseDto } from './dto/update-expense.dto'; -import { ExpenseDataService } from './expense-data.service'; -import { Expense } from './entities/expense.entity'; - -@Injectable() -export class ExpensesService { - public constructor(private expenseDataService: ExpenseDataService) { } - - public async findAll(): Promise { - return await this.expenseDataService.getAll(); - } - - public async findById(id: string): Promise { - const expense = await this.expenseDataService.getById(id); - if (!expense) { - throw new Error('No expense found'); - } - - return expense; - } - - public async create(expense: CreateExpenseDto): Promise { - return await this.expenseDataService.create(expense); - } - - public async update(expense: UpdateExpenseDto): Promise { - return await this.expenseDataService.update(expense); - } - - public async remove(id: string): Promise { - await this.expenseDataService.delete(id); - } -} diff --git a/src/merchants/entities/merchant.entity.ts b/src/merchants/entities/merchant.entity.ts index 87a61f9..0a5297f 100644 --- a/src/merchants/entities/merchant.entity.ts +++ b/src/merchants/entities/merchant.entity.ts @@ -5,6 +5,6 @@ export class Merchant { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ unique: true }) + @Column() name: string; } diff --git a/src/sub-categories/entities/sub-category.entity.ts b/src/sub-categories/entities/sub-category.entity.ts index f6bf282..87f85ae 100644 --- a/src/sub-categories/entities/sub-category.entity.ts +++ b/src/sub-categories/entities/sub-category.entity.ts @@ -5,6 +5,6 @@ export class SubCategory { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ unique: true }) + @Column() name: string; } diff --git a/src/tags/entities/tag.entity.ts b/src/tags/entities/tag.entity.ts index ed84b59..fdf7a2d 100644 --- a/src/tags/entities/tag.entity.ts +++ b/src/tags/entities/tag.entity.ts @@ -5,6 +5,6 @@ export class Tag { @PrimaryGeneratedColumn('uuid') id: string; - @Column({ unique: true }) + @Column() name: string; }