init
This commit is contained in:
commit
fdbe6f8eef
26
flake.lock
generated
Normal file
26
flake.lock
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1713248628,
|
||||||
|
"narHash": "sha256-NLznXB5AOnniUtZsyy/aPWOk8ussTuePp2acb9U+ISA=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "5672bc9dbf9d88246ddab5ac454e82318d094bb8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
45
flake.nix
Normal file
45
flake.nix
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
description = "A Nix-flake-based Node.js development environment";
|
||||||
|
|
||||||
|
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{ self, nixpkgs }:
|
||||||
|
let
|
||||||
|
overlays = [
|
||||||
|
(final: prev: rec {
|
||||||
|
nodejs = prev.nodejs_latest;
|
||||||
|
pnpm = prev.nodePackages.pnpm;
|
||||||
|
yarn = (prev.yarn.override { inherit nodejs; });
|
||||||
|
})
|
||||||
|
];
|
||||||
|
supportedSystems = [
|
||||||
|
"x86_64-linux"
|
||||||
|
"aarch64-linux"
|
||||||
|
"x86_64-darwin"
|
||||||
|
"aarch64-darwin"
|
||||||
|
];
|
||||||
|
forEachSupportedSystem =
|
||||||
|
f:
|
||||||
|
nixpkgs.lib.genAttrs supportedSystems (
|
||||||
|
system: f { pkgs = import nixpkgs { inherit overlays system; }; }
|
||||||
|
);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
devShells = forEachSupportedSystem (
|
||||||
|
{ pkgs }:
|
||||||
|
{
|
||||||
|
default = pkgs.mkShell {
|
||||||
|
packages = with pkgs; [
|
||||||
|
node2nix
|
||||||
|
nodejs
|
||||||
|
pnpm
|
||||||
|
yarn
|
||||||
|
prettierd
|
||||||
|
nodePackages.typescript-language-server
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
32
index.js
Normal file
32
index.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
const express = require('express')
|
||||||
|
const app = express()
|
||||||
|
const port = 3000
|
||||||
|
|
||||||
|
//// Swagger
|
||||||
|
const swaggerUi = require('swagger-ui-express')
|
||||||
|
const YAML = require('yaml')
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const file = fs.readFileSync('./open_api.yaml', 'utf8')
|
||||||
|
const swaggerDocument = YAML.parse(file)
|
||||||
|
|
||||||
|
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument))
|
||||||
|
// app.use(express.json())
|
||||||
|
|
||||||
|
// DB
|
||||||
|
const db = require('better-sqlite3')('mytest.db');
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
const accountsRoute = require('./routes/accounts')
|
||||||
|
const transactionsRoute = require('./routes/transactions')
|
||||||
|
|
||||||
|
app.use('/accounts', accountsRoute);
|
||||||
|
app.use('/transactions', transactionsRoute);
|
||||||
|
|
||||||
|
app.get('/', (req, res) => {
|
||||||
|
res.send('Hello World!')
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(port, () => {
|
||||||
|
console.log(`Example app listening on port ${port}`)
|
||||||
|
})
|
||||||
672
open_api.yaml
Normal file
672
open_api.yaml
Normal file
@ -0,0 +1,672 @@
|
|||||||
|
openapi: 3.0.0
|
||||||
|
info:
|
||||||
|
version: 1.0.0
|
||||||
|
title: Buchhaltungs-API
|
||||||
|
description: |
|
||||||
|
Buchhaltungs-API für das Web-Anwendungen-Projekt
|
||||||
|
servers:
|
||||||
|
- url: ../api/{apiVersion}
|
||||||
|
variables:
|
||||||
|
apiVersion:
|
||||||
|
enum:
|
||||||
|
- v1
|
||||||
|
default: v1
|
||||||
|
description: API-Version
|
||||||
|
paths:
|
||||||
|
/accounts:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Konten
|
||||||
|
description: |
|
||||||
|
Dieser Endpunkt liefert eine Liste aller Konten zurück.
|
||||||
|
operationId: book.getAccounts
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/AccountTree'
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Konten
|
||||||
|
description: |
|
||||||
|
Erstellt ein neues Konto.
|
||||||
|
|
||||||
|
Die Kontonummer muss in Verbindung mit dem übergeordneten Konto eindeutig sein.
|
||||||
|
operationId: book.createAccount
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
422:
|
||||||
|
description: Nicht ausführbare Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
/accounts/{account}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Konten
|
||||||
|
description: |
|
||||||
|
Dieser Endpunkt liefert die Details eines Kontos sowie
|
||||||
|
die Liste der Buchungen des Kontos.
|
||||||
|
parameters:
|
||||||
|
- name: account
|
||||||
|
in: path
|
||||||
|
description: |
|
||||||
|
Qualifizierter Name des Kontos
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
style: simple
|
||||||
|
operationId: book.getAccount
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/AccountDetails'
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Konto existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- Konten
|
||||||
|
description: |
|
||||||
|
Ändert die Kontodaten.
|
||||||
|
|
||||||
|
Die Kontonummer muss in Verbindung mit dem übergeordneten Konto eindeutig sein.
|
||||||
|
|
||||||
|
Der Kontotyp kann nur geändert werden, falls keine Buchungen mit dem Konto verknüpft sind.
|
||||||
|
parameters:
|
||||||
|
- name: account
|
||||||
|
in: path
|
||||||
|
description: |
|
||||||
|
Qualifizierter Name des Kontos
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
style: simple
|
||||||
|
operationId: book.updateAccount
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Account'
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Konto existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
422:
|
||||||
|
description: Nicht ausführbare Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- Konten
|
||||||
|
description: |
|
||||||
|
Löscht das Konto.
|
||||||
|
|
||||||
|
Diese Anfrage kann nur ausgeführt werden, falls keine Buchungen oder Unterkonten mehr mit dem Konto verknüpft sind.
|
||||||
|
parameters:
|
||||||
|
- name: account
|
||||||
|
in: path
|
||||||
|
description: |
|
||||||
|
Qualifizierter Name des Kontos
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
style: simple
|
||||||
|
operationId: book.deleteAccount
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Konto existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
422:
|
||||||
|
description: Nicht ausführbare Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
/transactions:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Buchungen
|
||||||
|
description: |
|
||||||
|
Dieser Endpunkt liefert eine Liste aller Buchungen zurück.
|
||||||
|
operationId: transaction.getTransactions
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/TransactionListItem'
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Buchungen
|
||||||
|
description: |
|
||||||
|
Erstellt eine neue Buchung.
|
||||||
|
operationId: transaction.createTransaction
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
additionalProperties: false
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
422:
|
||||||
|
description: Ungültige Transaktion
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
/transactions/{id}:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Buchungen
|
||||||
|
description: |
|
||||||
|
Zeigt die Details einer Buchung mit allen Konten und Beträgen an.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
description: Buchungs-ID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
style: simple
|
||||||
|
operationId: transaction.getTransaction
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Transaktion existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- Buchungen
|
||||||
|
description: |
|
||||||
|
Aktualisiert die Buchung.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
description: Buchungs-ID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
style: simple
|
||||||
|
operationId: transaction.updateTransaction
|
||||||
|
requestBody:
|
||||||
|
required: true
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Transaction'
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Transaktion existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
422:
|
||||||
|
description: Ungültige Transaktion
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
delete:
|
||||||
|
tags:
|
||||||
|
- Buchungen
|
||||||
|
description: |
|
||||||
|
Löscht die Buchung aus allen Konten.
|
||||||
|
parameters:
|
||||||
|
- name: id
|
||||||
|
in: path
|
||||||
|
description: Buchungs-ID
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
style: simple
|
||||||
|
operationId: transaction.deleteTransaction
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
404:
|
||||||
|
description: Transaktion existiert nicht
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
/reset:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Wartung
|
||||||
|
description: |
|
||||||
|
Dieser Endpunkt setzt den Datenbestand zurück.
|
||||||
|
operationId: admin.doReset
|
||||||
|
responses:
|
||||||
|
204:
|
||||||
|
description: OK
|
||||||
|
400:
|
||||||
|
description: Ungültige Anfrage
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
500:
|
||||||
|
description: Unerwarteter Fehler
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/Error'
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
Identifier:
|
||||||
|
type: integer
|
||||||
|
minimum: 1
|
||||||
|
maximum: 99999999
|
||||||
|
description: ID
|
||||||
|
example: 1
|
||||||
|
CurrencyAmount:
|
||||||
|
type: number
|
||||||
|
multipleOf: 0.01
|
||||||
|
description: Geldbetrag in Euro
|
||||||
|
example: 225.17
|
||||||
|
CurrencyNonZeroAmount:
|
||||||
|
description: Geldbetrag in Euro, der nicht Null ist
|
||||||
|
oneOf:
|
||||||
|
- type: number
|
||||||
|
multipleOf: 0.01
|
||||||
|
minimum: 0
|
||||||
|
exclusiveMinimum: true
|
||||||
|
description: Positiver Geldbetrag in Euro
|
||||||
|
example: 25.17
|
||||||
|
- type: number
|
||||||
|
multipleOf: 0.01
|
||||||
|
maximum: 0
|
||||||
|
exclusiveMaximum: true
|
||||||
|
description: Negativer Geldbetrag in Euro
|
||||||
|
example: -93.11
|
||||||
|
Account:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
$ref: '#/components/schemas/AccountNumber'
|
||||||
|
name:
|
||||||
|
$ref: '#/components/schemas/AccountName'
|
||||||
|
description:
|
||||||
|
$ref: '#/components/schemas/AccountDescription'
|
||||||
|
type:
|
||||||
|
$ref: '#/components/schemas/AccountType'
|
||||||
|
parentAccount:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
required:
|
||||||
|
- number
|
||||||
|
- name
|
||||||
|
- type
|
||||||
|
additionalProperties: false
|
||||||
|
AccountTree:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
$ref: '#/components/schemas/AccountNumber'
|
||||||
|
name:
|
||||||
|
$ref: '#/components/schemas/AccountName'
|
||||||
|
qualifiedName:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
description:
|
||||||
|
$ref: '#/components/schemas/AccountDescription'
|
||||||
|
type:
|
||||||
|
$ref: '#/components/schemas/AccountType'
|
||||||
|
balance:
|
||||||
|
$ref: '#/components/schemas/CurrencyAmount'
|
||||||
|
localBalance:
|
||||||
|
$ref: '#/components/schemas/CurrencyAmount'
|
||||||
|
subaccounts:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/AccountTree'
|
||||||
|
required:
|
||||||
|
- number
|
||||||
|
- name
|
||||||
|
- qualifiedName
|
||||||
|
- type
|
||||||
|
- balance
|
||||||
|
- localBalance
|
||||||
|
- subaccounts
|
||||||
|
additionalProperties: false
|
||||||
|
AccountDetails:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
number:
|
||||||
|
$ref: '#/components/schemas/AccountNumber'
|
||||||
|
name:
|
||||||
|
$ref: '#/components/schemas/AccountName'
|
||||||
|
qualifiedName:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
description:
|
||||||
|
$ref: '#/components/schemas/AccountDescription'
|
||||||
|
type:
|
||||||
|
$ref: '#/components/schemas/AccountType'
|
||||||
|
balance:
|
||||||
|
$ref: '#/components/schemas/CurrencyAmount'
|
||||||
|
localBalance:
|
||||||
|
$ref: '#/components/schemas/CurrencyAmount'
|
||||||
|
entries:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/Entry'
|
||||||
|
required:
|
||||||
|
- number
|
||||||
|
- name
|
||||||
|
- qualifiedName
|
||||||
|
- type
|
||||||
|
- balance
|
||||||
|
- localBalance
|
||||||
|
- entries
|
||||||
|
additionalProperties: false
|
||||||
|
AccountNumber:
|
||||||
|
type: integer
|
||||||
|
minimum: 1
|
||||||
|
maximum: 99999999
|
||||||
|
description: Kontonummer (wird insbesondere zur Sortierung genutzt)
|
||||||
|
example: 1100
|
||||||
|
AccountName:
|
||||||
|
type: string
|
||||||
|
minLength: 3
|
||||||
|
maxLength: 32
|
||||||
|
pattern: '^[a-zA-Z0-9äöüßÄÖÜẞ_ -]*$'
|
||||||
|
description: Name des Kontos
|
||||||
|
example: Aktiva
|
||||||
|
AccountQualifiedName:
|
||||||
|
type: string
|
||||||
|
minLength: 3
|
||||||
|
description: Name des Kontos mit übergeordneten Konten (qualifizierter Name)
|
||||||
|
example: Aktiva:Barvermögen:Bargeld
|
||||||
|
AccountDescription:
|
||||||
|
type: string
|
||||||
|
minLength: 3
|
||||||
|
maxLength: 64
|
||||||
|
description: Beschreibung des Kontos
|
||||||
|
example: Girokonto bei der Musterbank eG
|
||||||
|
AccountType:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- default
|
||||||
|
- meta
|
||||||
|
description: Art des Kontos (nur Platzhalter für Unterkonten oder eigene Buchungen erlaubt)
|
||||||
|
example: default
|
||||||
|
Entry:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
postingDate:
|
||||||
|
$ref: '#/components/schemas/EntryPostingDate'
|
||||||
|
valueDate:
|
||||||
|
$ref: '#/components/schemas/EntryValueDate'
|
||||||
|
title:
|
||||||
|
$ref: '#/components/schemas/EntryTitle'
|
||||||
|
amount:
|
||||||
|
$ref: '#/components/schemas/CurrencyNonZeroAmount'
|
||||||
|
label:
|
||||||
|
$ref: '#/components/schemas/EntryLabel'
|
||||||
|
offsetAccounts:
|
||||||
|
type: string
|
||||||
|
description: Gegenkonto (ggf. mehrere bei mehrteiliger Buchung)
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- postingDate
|
||||||
|
- valueDate
|
||||||
|
- title
|
||||||
|
- amount
|
||||||
|
- offsetAccounts
|
||||||
|
additionalProperties: false
|
||||||
|
EntryPostingDate:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: Buchungsdatum
|
||||||
|
EntryValueDate:
|
||||||
|
type: string
|
||||||
|
format: date
|
||||||
|
description: Valuta (Wertstellungsdatum)
|
||||||
|
EntryTitle:
|
||||||
|
type: string
|
||||||
|
minLength: 3
|
||||||
|
maxLength: 64
|
||||||
|
description: Buchungstitel
|
||||||
|
example: Semesterbeitrag SoSe 2024
|
||||||
|
EntryLabel:
|
||||||
|
type: string
|
||||||
|
minLength: 3
|
||||||
|
maxLength: 64
|
||||||
|
description: Buchungstitel des Kontos
|
||||||
|
Transaction:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
postingDate:
|
||||||
|
$ref: '#/components/schemas/EntryPostingDate'
|
||||||
|
valueDate:
|
||||||
|
$ref: '#/components/schemas/EntryValueDate'
|
||||||
|
title:
|
||||||
|
$ref: '#/components/schemas/EntryTitle'
|
||||||
|
entries:
|
||||||
|
type: array
|
||||||
|
minItems: 2
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
account:
|
||||||
|
$ref: '#/components/schemas/AccountQualifiedName'
|
||||||
|
amount:
|
||||||
|
$ref: '#/components/schemas/CurrencyNonZeroAmount'
|
||||||
|
label:
|
||||||
|
$ref: '#/components/schemas/EntryLabel'
|
||||||
|
required:
|
||||||
|
- account
|
||||||
|
- amount
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- postingDate
|
||||||
|
- valueDate
|
||||||
|
- title
|
||||||
|
- entries
|
||||||
|
additionalProperties: false
|
||||||
|
TransactionListItem:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
$ref: '#/components/schemas/Identifier'
|
||||||
|
postingDate:
|
||||||
|
$ref: '#/components/schemas/EntryPostingDate'
|
||||||
|
valueDate:
|
||||||
|
$ref: '#/components/schemas/EntryValueDate'
|
||||||
|
title:
|
||||||
|
$ref: '#/components/schemas/EntryTitle'
|
||||||
|
required:
|
||||||
|
- id
|
||||||
|
- postingDate
|
||||||
|
- valueDate
|
||||||
|
- title
|
||||||
|
additionalProperties: false
|
||||||
|
Error:
|
||||||
|
required:
|
||||||
|
- message
|
||||||
|
properties:
|
||||||
|
code:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
message:
|
||||||
|
type: string
|
||||||
|
additionalProperties: true
|
||||||
|
|
||||||
1153
package-lock.json
generated
Normal file
1153
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
package.json
Normal file
18
package.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "uni-backend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Our backend",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"better-sqlite3": "^9.5.0",
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"express": "^4.19.2",
|
||||||
|
"swagger-ui-express": "^5.0.0",
|
||||||
|
"yaml": "^2.4.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
25
routes/accounts.js
Normal file
25
routes/accounts.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get("/", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
router.post("/", (req, res) => {
|
||||||
|
res.send(req.params);
|
||||||
|
})
|
||||||
|
|
||||||
|
router.get("/:account", (req, res) => {
|
||||||
|
res.send(req.params);
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put("/:account", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
router.delete("/:account", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
0
routes/reset.js
Normal file
0
routes/reset.js
Normal file
25
routes/transactions.js
Normal file
25
routes/transactions.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
router.get("/", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
router.post("/", (req, res) => {
|
||||||
|
res.send(req.params);
|
||||||
|
})
|
||||||
|
|
||||||
|
router.get("/:id", (req, res) => {
|
||||||
|
res.send(req.params);
|
||||||
|
})
|
||||||
|
|
||||||
|
router.put("/:id", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
router.delete("/:id", (req, res) => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
11
sql/create_account.sql
Normal file
11
sql/create_account.sql
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
INSERT INTO accounts(
|
||||||
|
name,
|
||||||
|
qualifiedName,
|
||||||
|
description,
|
||||||
|
type,
|
||||||
|
balance,
|
||||||
|
localBalance,
|
||||||
|
)
|
||||||
|
VALUES (
|
||||||
|
'meins', 'Aktiva:meins', 'Mein Geld lol', 'normal', 0.0, 0.0
|
||||||
|
)
|
||||||
26
sql/create_db.sql
Normal file
26
sql/create_db.sql
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
CREATE TABLE accounts (
|
||||||
|
account_id INTEGER PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
qualifiedName TEXT NOT NULL,
|
||||||
|
description TEXT NOT NULL,
|
||||||
|
type TEXT NOT NULL,
|
||||||
|
balance FLOAT NOT NULL,
|
||||||
|
localBalance FLOAT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE transactions (
|
||||||
|
transaction_id INTEGER PRIMARY KEY,
|
||||||
|
postingDate TEXT NOT NULL,
|
||||||
|
valueDate TEXT,
|
||||||
|
title TEXT NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE transaction_entries (
|
||||||
|
transaction_id INT,
|
||||||
|
account_id INT,
|
||||||
|
amount FLOAT,
|
||||||
|
label TEXT,
|
||||||
|
FOREIGN KEY (transaction_id) REFERENCES transactions(transaction_id)
|
||||||
|
FOREIGN KEY (account_id) REFERENCES account(account_id)
|
||||||
|
PRIMARY KEY (transaction_id, account_id)
|
||||||
|
);
|
||||||
Loading…
x
Reference in New Issue
Block a user