Compare commits

...

29 commits

Author SHA1 Message Date
9bd5a15480
Merge pull request 'fix(deps): update dependency org.springdoc:springdoc-openapi-starter-webmvc-ui to v2.8.9' (!300) from renovate/dependencies-(major-and-minor) into main
All checks were successful
Build docs / build-docs (push) Successful in 18s
Release / Release (push) Successful in 1m21s
Release / Build Frontend Image (push) Successful in 2m23s
Release / Build Backend Image (push) Successful in 3m58s
Reviewed-on: #300
Reviewed-by: Jan-Marlon Leibl <jleibl@proton.me>
2025-06-12 06:27:53 +00:00
ce3af8915d
Merge pull request 'fix(deps): update all non-major dependencies' (!293) from renovate/all-minor-patch into main
Some checks failed
Release / Build Backend Image (push) Blocked by required conditions
Release / Build Frontend Image (push) Blocked by required conditions
Build docs / build-docs (push) Has been cancelled
Release / Release (push) Has been cancelled
Reviewed-on: #293
2025-06-12 06:27:37 +00:00
684cec7d56
Merge pull request 'chore(deps): update devdependencies (non-major)' (!298) from renovate/devdependencies-(non-major) into main
Some checks failed
Release / Build Backend Image (push) Blocked by required conditions
Release / Build Frontend Image (push) Blocked by required conditions
Build docs / build-docs (push) Has been cancelled
Release / Release (push) Has been cancelled
Reviewed-on: #298
2025-06-12 06:27:29 +00:00
a7b5c42558
chore(deps): update devdependencies (non-major)
All checks were successful
CI / Get Changed Files (pull_request) Successful in 14s
Label PRs based on size / Check PR size (pull_request) Successful in 29s
Claude PR Review / claude-code (pull_request) Successful in 36s
Pull Request Labeler / labeler (pull_request_target) Successful in 11s
CI / oxlint (pull_request) Successful in 46s
CI / prettier (pull_request) Successful in 52s
CI / eslint (pull_request) Successful in 1m8s
CI / Backend Tests (pull_request) Has been skipped
CI / test-build (pull_request) Successful in 1m25s
CI / Checkstyle Main (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Successful in 17s
CI / Playwright (pull_request) Successful in 2m24s
2025-06-11 13:03:20 +00:00
9207c070fd
fix(deps): update dependency org.springdoc:springdoc-openapi-starter-webmvc-ui to v2.8.9
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 6s
CI / Get Changed Files (pull_request) Successful in 16s
CI / eslint (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 16s
CI / oxlint (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 22s
CI / test-build (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Successful in 20s
CI / Playwright (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Successful in 1m47s
CI / Backend Tests (pull_request) Successful in 3m17s
2025-06-11 13:03:03 +00:00
4bcc6b45b4
fix(deps): update all non-major dependencies
All checks were successful
CI / Get Changed Files (pull_request) Successful in 18s
Pull Request Labeler / labeler (pull_request_target) Successful in 12s
Label PRs based on size / Check PR size (pull_request) Successful in 15s
CI / eslint (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 24s
CI / test-build (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Successful in 21s
CI / Checkstyle Main (pull_request) Successful in 2m13s
CI / Backend Tests (pull_request) Successful in 3m25s
2025-06-11 13:02:58 +00:00
f754a6fc72
Merge pull request 'chore: Add some more docs idc' (!312) from docs/idc into main
All checks were successful
Build docs / build-docs (push) Successful in 12s
Reviewed-on: #312
2025-06-11 12:54:20 +00:00
96aca3b293 chore: Add some more docs idc
All checks were successful
CI / Get Changed Files (pull_request) Successful in 9s
CI / Backend Tests (pull_request) Has been skipped
CI / eslint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
Pull Request Labeler / labeler (pull_request_target) Successful in 9s
CI / Docker frontend validation (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 12s
CI / prettier (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m13s
2025-06-11 14:51:20 +02:00
a411234714
Merge pull request 'docs: add deployment docs' (!311) from docs/deployment into main
All checks were successful
Build docs / build-docs (push) Successful in 12s
Reviewed-on: #311
Reviewed-by: Phan Huy Tran <ptran@noreply.localhost>
2025-06-11 12:22:27 +00:00
52a3e6aadc
docs: add deployment docs
All checks were successful
CI / Get Changed Files (pull_request) Successful in 9s
CI / eslint (pull_request) Has been skipped
CI / Backend Tests (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
Pull Request Labeler / labeler (pull_request_target) Successful in 11s
CI / Docker backend validation (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 15s
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m30s
2025-06-11 14:21:09 +02:00
5ea3ff73a0
Merge pull request 'chore: Add docs for coinflip' (!309) from docs/coinflip into main
All checks were successful
Build docs / build-docs (push) Successful in 12s
Reviewed-on: #309
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
Reviewed-by: Jan-Marlon Leibl <jleibl@proton.me>
2025-06-11 12:19:21 +00:00
050c272226 chore: Add docs for coinflip
All checks were successful
CI / Get Changed Files (pull_request) Successful in 10s
CI / eslint (pull_request) Has been skipped
CI / Backend Tests (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
Pull Request Labeler / labeler (pull_request_target) Successful in 10s
CI / Docker frontend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 10s
Claude PR Review / claude-code (pull_request) Successful in 1m15s
2025-06-11 14:18:28 +02:00
75deee3f9f
Merge pull request 'docs: add slots docs' (!310) from docs-slots into main
All checks were successful
Build docs / build-docs (push) Successful in 12s
Reviewed-on: #310
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
2025-06-11 12:15:44 +00:00
Phan Huy Tran
4af605ef96 docs: add slots docs
All checks were successful
CI / Get Changed Files (pull_request) Successful in 9s
CI / Backend Tests (pull_request) Has been skipped
CI / eslint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
Pull Request Labeler / labeler (pull_request_target) Successful in 11s
CI / Docker backend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 15s
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m37s
2025-06-11 14:14:33 +02:00
6737eb9e4a
Merge pull request 'docs: Add Auth Docs' (!307) from docs/auth into main
All checks were successful
Build docs / build-docs (push) Successful in 14s
Reviewed-on: #307
Reviewed-by: Phan Huy Tran <ptran@noreply.localhost>
2025-06-11 12:02:25 +00:00
4619f787f0
add pdf to gitignore
Some checks failed
Claude PR Review / claude-code (pull_request) Successful in 26s
Pull Request Labeler / labeler (pull_request_target) Successful in 22s
CI / Get Changed Files (pull_request) Successful in 34s
Label PRs based on size / Check PR size (pull_request) Successful in 35s
CI / Backend Tests (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
CI / eslint (pull_request) Failing after 13m51s
2025-06-11 13:58:26 +02:00
3ca0b5a3c4
docs: Add API and JWT acronyms to documentation 2025-06-11 13:58:25 +02:00
7e30e191b4
Merge pull request 'docs: add dice docs' (!308) from docs-dice into main
All checks were successful
Build docs / build-docs (push) Successful in 12s
Reviewed-on: #308
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
2025-06-11 11:57:03 +00:00
Phan Huy Tran
140bd44d66 chore: rebase
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 4s
CI / Get Changed Files (pull_request) Successful in 13s
CI / Backend Tests (pull_request) Has been skipped
CI / eslint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 15s
CI / Docker backend validation (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 27s
2025-06-11 13:55:31 +02:00
Phan Huy Tran
1d6ac261e0 docs: add dice docs 2025-06-11 13:54:50 +02:00
9deb92ad13
Merge pull request 'chore: Add Project-Architecture' (!306) from docs/architecture into main
All checks were successful
Build docs / build-docs (push) Successful in 13s
Reviewed-on: #306
Reviewed-by: Phan Huy Tran <ptran@noreply.localhost>
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
2025-06-11 11:53:10 +00:00
0345df3a30 chore: Add Project-Architecture
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 8s
Label PRs based on size / Check PR size (pull_request) Successful in 16s
Claude PR Review / claude-code (pull_request) Successful in 1m13s
CI / Get Changed Files (pull_request) Successful in 13s
CI / eslint (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / Backend Tests (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
2025-06-11 13:49:14 +02:00
5bd3f554e2
Merge pull request 'chore: Add CI section to docs' (!305) from docs/CI into main
All checks were successful
Build docs / build-docs (push) Successful in 14s
Reviewed-on: #305
Reviewed-by: Phan Huy Tran <ptran@noreply.localhost>
2025-06-11 11:25:21 +00:00
59bb910f05 chore: Add CI section to docs
All checks were successful
CI / Get Changed Files (pull_request) Successful in 10s
CI / Backend Tests (pull_request) Has been skipped
CI / eslint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
Pull Request Labeler / labeler (pull_request_target) Successful in 8s
CI / oxlint (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 13s
CI / Docker backend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m29s
2025-06-11 13:22:15 +02:00
e5155c072f
Merge pull request 'docs: replace logos with hitec logo' (!302) from logo into main
All checks were successful
Build docs / build-docs (push) Successful in 13s
Reviewed-on: #302
Reviewed-by: Constantin Simonis <constantin@simonis.lol>
2025-06-11 10:55:17 +00:00
Phan Huy Tran
922c95c212 docs: add logo to deckblatt
All checks were successful
Pull Request Labeler / labeler (pull_request_target) Successful in 17s
Label PRs based on size / Check PR size (pull_request) Successful in 30s
CI / Get Changed Files (pull_request) Successful in 34s
CI / eslint (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m47s
CI / Backend Tests (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
2025-06-11 12:45:21 +02:00
Phan Huy Tran
c5b44f3f29 docs: replace logo 2025-06-11 12:41:05 +02:00
fad280104d
Merge pull request 'docs: add docs' (!301) from docs into main
All checks were successful
Build docs / build-docs (push) Successful in 27s
Reviewed-on: #301
Reviewed-by: Jan K9f <jan@kjan.email>
2025-06-11 10:28:04 +00:00
Phan Huy Tran
9cb813bf41 docs: add docs
All checks were successful
CI / Get Changed Files (pull_request) Successful in 30s
Pull Request Labeler / labeler (pull_request_target) Successful in 15s
CI / Backend Tests (pull_request) Has been skipped
Label PRs based on size / Check PR size (pull_request) Successful in 29s
CI / eslint (pull_request) Has been skipped
CI / Checkstyle Main (pull_request) Has been skipped
CI / oxlint (pull_request) Has been skipped
CI / Docker frontend validation (pull_request) Has been skipped
CI / prettier (pull_request) Has been skipped
CI / Docker backend validation (pull_request) Has been skipped
CI / test-build (pull_request) Has been skipped
CI / Playwright (pull_request) Has been skipped
Claude PR Review / claude-code (pull_request) Successful in 1m42s
2025-06-11 12:24:18 +02:00
94 changed files with 4968 additions and 12 deletions

View file

@ -50,7 +50,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server:3.5.0")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client:3.5.0")
runtimeOnly("org.postgresql:postgresql")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.8")
implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.8.9")
implementation("io.jsonwebtoken:jjwt-api:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.12.6")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.12.6")

View file

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View file

@ -36,7 +36,7 @@
"@types/jasmine": "~5.1.0",
"angular-eslint": "20.0.0",
"eslint": "^9.28.0",
"jasmine-core": "~5.7.0",
"jasmine-core": "~5.8.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
@ -44,7 +44,7 @@
"karma-jasmine-html-reporter": "~2.1.0",
"prettier": "^3.4.2",
"typescript": "~5.8.0",
"typescript-eslint": "8.33.1",
"typescript-eslint": "8.34.0",
},
},
},
@ -687,9 +687,9 @@
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.33.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/type-utils": "8.33.1", "@typescript-eslint/utils": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.33.1", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A=="],
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.34.0", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/type-utils": "8.34.0", "@typescript-eslint/utils": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.34.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.33.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/types": "8.33.1", "@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/visitor-keys": "8.33.1", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA=="],
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.34.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA=="],
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.33.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.33.1", "@typescript-eslint/types": "^8.33.1", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw=="],
@ -697,7 +697,7 @@
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.33.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g=="],
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.33.1", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/utils": "8.33.1", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww=="],
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.34.0", "", { "dependencies": { "@typescript-eslint/typescript-estree": "8.34.0", "@typescript-eslint/utils": "8.34.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg=="],
"@typescript-eslint/types": ["@typescript-eslint/types@8.33.1", "", {}, "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg=="],
@ -705,7 +705,7 @@
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.33.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/types": "8.33.1", "@typescript-eslint/typescript-estree": "8.33.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ=="],
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.33.1", "", { "dependencies": { "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" } }, "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ=="],
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "eslint-visitor-keys": "^4.2.0" } }, "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA=="],
"@vitejs/plugin-basic-ssl": ["@vitejs/plugin-basic-ssl@2.0.0", "", { "peerDependencies": { "vite": "^6.0.0" } }, "sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA=="],
@ -1221,7 +1221,7 @@
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
"jasmine-core": ["jasmine-core@5.7.1", "", {}, "sha512-QnurrtpKsPoixxG2R3d1xP0St/2kcX5oTZyDyQJMY+Vzi/HUlu1kGm+2V8Tz+9lV991leB1l0xcsyz40s9xOOw=="],
"jasmine-core": ["jasmine-core@5.8.0", "", {}, "sha512-Q9dqmpUAfptwyueW3+HqBOkSuYd9I/clZSSfN97wXE/Nr2ROFNCwIBEC1F6kb3QXS9Fcz0LjFYSDQT+BiwjuhA=="],
"jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="],
@ -1755,7 +1755,7 @@
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
"typescript-eslint": ["typescript-eslint@8.33.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.33.1", "@typescript-eslint/parser": "8.33.1", "@typescript-eslint/utils": "8.33.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-AgRnV4sKkWOiZ0Kjbnf5ytTJXMUZQ0qhSVdQtDNYLPLnjsATEYhaO94GlRQwi4t4gO8FfjM6NnikHeKjUm8D7A=="],
"typescript-eslint": ["typescript-eslint@8.34.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.34.0", "@typescript-eslint/parser": "8.34.0", "@typescript-eslint/utils": "8.34.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-MRpfN7uYjTrTGigFCt8sRyNqJFhjN0WwZecldaqhWm+wy0gaRt8Edb/3cuUy0zdq2opJWT6iXINKAtewnDOltQ=="],
"ua-parser-js": ["ua-parser-js@0.7.40", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ=="],
@ -1947,10 +1947,30 @@
"@tufjs/models/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0" } }, "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils": ["@typescript-eslint/utils@8.34.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
"@typescript-eslint/parser/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0" } }, "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw=="],
"@typescript-eslint/parser/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"@typescript-eslint/parser/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.34.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.34.0", "@typescript-eslint/tsconfig-utils": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg=="],
"@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.33.1", "", { "dependencies": { "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" } }, "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.34.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.34.0", "@typescript-eslint/tsconfig-utils": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg=="],
"@typescript-eslint/type-utils/@typescript-eslint/utils": ["@typescript-eslint/utils@8.34.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ=="],
"@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.33.1", "", { "dependencies": { "@typescript-eslint/types": "8.33.1", "eslint-visitor-keys": "^4.2.0" } }, "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/visitor-keys/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"accepts/negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
"adjust-sourcemap-loader/loader-utils": ["loader-utils@2.0.4", "", { "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", "json5": "^2.1.2" } }, "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw=="],
@ -2121,6 +2141,8 @@
"tar/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
"typescript-eslint/@typescript-eslint/utils": ["@typescript-eslint/utils@8.34.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/typescript-estree": "8.34.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ=="],
"vite/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"vite/tinyglobby": ["tinyglobby@0.2.14", "", { "dependencies": { "fdir": "^6.4.4", "picomatch": "^4.0.2" } }, "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ=="],
@ -2185,6 +2207,30 @@
"@tufjs/models/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/scope-manager/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.34.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.34.0", "@typescript-eslint/tsconfig-utils": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg=="],
"@typescript-eslint/parser/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.34.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.34.0", "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw=="],
"@typescript-eslint/parser/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.34.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA=="],
"@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.34.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.34.0", "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.34.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0" } }, "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw=="],
"@typescript-eslint/type-utils/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
@ -2269,6 +2315,12 @@
"tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.34.0", "", { "dependencies": { "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0" } }, "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@8.34.0", "", {}, "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.34.0", "", { "dependencies": { "@typescript-eslint/project-service": "8.34.0", "@typescript-eslint/tsconfig-utils": "8.34.0", "@typescript-eslint/types": "8.34.0", "@typescript-eslint/visitor-keys": "8.34.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg=="],
"webpack-dev-server/chokidar/fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"webpack-dev-server/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@ -2301,6 +2353,16 @@
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.34.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.34.0", "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.34.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/parser/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"@typescript-eslint/type-utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"cacache/glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"karma-coverage/istanbul-lib-instrument/@babel/core/@babel/generator": ["@babel/generator@7.27.5", "", { "dependencies": { "@babel/parser": "^7.27.5", "@babel/types": "^7.27.3", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" } }, "sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw=="],
@ -2317,14 +2379,24 @@
"karma/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.34.0", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.34.0", "@typescript-eslint/types": "^8.34.0", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.34.0", "", { "peerDependencies": { "typescript": ">=4.8.4 <5.9.0" } }, "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"webpack-dev-server/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@emnapi/core/@emnapi/wasi-threads/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@typescript-eslint/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"karma/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"karma/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"typescript-eslint/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
}
}

View file

@ -46,7 +46,7 @@
"@types/jasmine": "~5.1.0",
"angular-eslint": "20.0.0",
"eslint": "^9.28.0",
"jasmine-core": "~5.7.0",
"jasmine-core": "~5.8.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
@ -54,6 +54,6 @@
"karma-jasmine-html-reporter": "~2.1.0",
"prettier": "^3.4.2",
"typescript": "~5.8.0",
"typescript-eslint": "8.33.1"
"typescript-eslint": "8.34.0"
}
}

132
projektdokumentation/.gitignore vendored Normal file
View file

@ -0,0 +1,132 @@
## Core latex/pdflatex auxiliary files:
*.aux
*.lof
*.log
*.lot
*.fls
*.out
*.toc
*.pdf
## Intermediate documents:
*.dvi
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
# *.eps
# *.pdf
## Bibliography auxiliary files (bibtex/biblatex/biber):
*.bbl
*.bcf
*.blg
*-blx.aux
*-blx.bib
*.brf
*.run.xml
## Build tool auxiliary files:
*.fdb_latexmk
*.synctex
*.synctex.gz
*.synctex.gz(busy)
*.pdfsync
## Auxiliary and intermediate files from other packages:
# algorithms
*.alg
*.loa
# achemso
acs-*.bib
# amsthm
*.thm
# beamer
*.nav
*.snm
*.vrb
#(e)ledmac/(e)ledpar
*.end
*.[1-9]
*.[1-9][0-9]
*.[1-9][0-9][0-9]
*.[1-9]R
*.[1-9][0-9]R
*.[1-9][0-9][0-9]R
*.eledsec[1-9]
*.eledsec[1-9]R
*.eledsec[1-9][0-9]
*.eledsec[1-9][0-9]R
*.eledsec[1-9][0-9][0-9]
*.eledsec[1-9][0-9][0-9]R
# glossaries
*.acn
*.acr
*.glg
*.glo
*.gls
# gnuplottex
*-gnuplottex-*
# hyperref
*.brf
# knitr
*-concordance.tex
*.tikz
*-tikzDictionary
# listings
*.lol
# makeidx
*.idx
*.ilg
*.ind
*.ist
# minitoc
*.maf
*.mtc
*.mtc0
# minted
_minted*
*.pyg
# morewrites
*.mw
# nomencl
*.nlo
# sagetex
*.sagetex.sage
*.sagetex.py
*.sagetex.scmd
# sympy
*.sout
*.sympy
sympy-plots-for-*.tex/
# todonotes
*.tdo
# xindy
*.xdy
# WinEdt
*.bak
*.sav
/tmp/
# idea
.idea/
Projektdokumentation.syntex(busy)

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>VorlageFachinformatiker</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>net.sourceforge.texlipse.builder.TexlipseBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>net.sourceforge.texlipse.builder.TexlipseNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,13 @@
#TeXlipse project settings
#Fri Jan 27 09:15:16 CET 2012
builderNum=2
outputDir=
makeIndSty=
bibrefDir=
outputFormat=pdf
tempDir=tmp
mainTexFile=Projektdokumentation.tex
outputFile=Projektdokumentation.pdf
langSpell=de
markDer=true
srcDir=

View file

@ -0,0 +1,40 @@
% !TEX root = Projektdokumentation.tex
% Es werden nur die Abkürzungen aufgelistet, die mit \ac definiert und auch benutzt wurden.
%
% \acro{VERSIS}{Versicherungsinformationssystem\acroextra{ (Bestandsführungssystem)}}
% Ergibt in der Liste: VERSIS Versicherungsinformationssystem (Bestandsführungssystem)
% Im Text aber: \ac{VERSIS} -> Versicherungsinformationssystem (VERSIS)
% Hinweis: allgemein bekannte Abkürzungen wie z.B. bzw. u.a. müssen nicht ins Abkürzungsverzeichnis aufgenommen werden
% Hinweis: allgemein bekannte IT-Begriffe wie Datenbank oder Programmiersprache müssen nicht erläutert werden,
% aber ggfs. Fachbegriffe aus der Domäne des Prüflings (z.B. Versicherung)
% Die Option (in den eckigen Klammern) enthält das längste Label oder
% einen Platzhalter der die Breite der linken Spalte bestimmt.
\begin{acronym}[WWWWW]
\acro{API}{Application Programming Interface}
\acro{CI}{Continuous Integration}
\acro{CI/CD}{Continuous Integration/Continuous Deployment}
\acro{CLI}{Command Line Interface}
\acro{CRM}{Customer Relationship Management}
\acro{CRON}{Vorgangsausführung gemäß geplanten Zeitabläufen für UNIX Programme}
\acro{E2E}{End-to-End}
\acro{eCommerce}{Electronic Commerce}
\acro{ERM}{Entity-Relationship-Model}
\acro{GUI}{Graphical User Interface}
\acro{HTTP}{Hypertext Transfer Protocol}
\acro{IDE}{Integrated Development Environment}
\acro{IX}{Intex Fusion Pro Omnichannel CRM}
\acro{JSON}{JavaScript Object Notation}
\acro{M2}{\textsc{Magento 2} eCommerce Platform}
\acro{NSD}{\textsc{neusta software development} GmbH}
\acro{NXP}{\textsc{neusta experience} GmbH}
\acro{PHP}{Hypertext Preprocessor}\acused{PHP}
\acro{SQL}{Structured Query Language}
\acro{URL}{Uniform Resource Locator}\acused{URL}
\acro{VM}{Virtual Machine}
\acro{XML}{Extensible Markup Language}
\acro{API}{Application Programming Interface}
\acro{JWT}{JSON Web Token}
\end{acronym}

View file

@ -0,0 +1,85 @@
% !TEX root = ../Projektdokumentation.tex
% Abkürzungen, ggfs. mit korrektem Leerraum
\newcommand{\bs}{$\backslash$\xspace}
\newcommand{\bspw}{bspw.\xspace}
\newcommand{\bzw}{bzw.\xspace}
\newcommand{\ca}{ca.\xspace}
\newcommand{\dahe}{\mbox{d.\,h.}\xspace}
\newcommand{\etc}{etc.\xspace}
\newcommand{\eur}[1]{\mbox{#1\,\texteuro}\xspace}
\newcommand{\evtl}{evtl.\xspace}
\newcommand{\ggfs}{ggfs.\xspace}
\newcommand{\Ggfs}{Ggfs.\xspace}
\newcommand{\gqq}[1]{\glqq{}#1\grqq{}}
\newcommand{\inkl}{inkl.\xspace}
\newcommand{\insb}{insb.\xspace}
\newcommand{\ua}{\mbox{u.\,a.}\xspace}
\newcommand{\usw}{usw.\xspace}
\newcommand{\Vgl}{Vgl.\xspace}
\newcommand{\zB}{\mbox{z.\,B.}\xspace}
% Befehle für häufig anfallende Aufgaben
\newcommand{\Abbildung}[1]{\autoref{fig:#1}}
\newcommand{\Anhang}[1]{\appendixname{}~\ref{#1}: \nameref{#1} \vpageref{#1}}
\newcommand{\includegraphicsKeepAspectRatio}[2]{\includegraphics[width=#2\textwidth,height=#2\textheight,keepaspectratio]{#1}}
\newcommand{\Zitat}[2][\empty]{\ifthenelse{\equal{#1}{\empty}}{\citep{#2}}{\citep[#1]{#2}}}
\newcommand{\Autor}[1]{\textsc{#1}} % zum Ausgeben von Autoren
\newcommand{\itemd}[2]{\item{\textbf{#1}}\\{#2}} % erzeugt ein Listenelement mit fetter Überschrift
% fügt Tabellen aus einer TEX-Datei ein
\newcommand{\tabelle}[3] % Parameter: caption, label, file
{\begin{table}[htbp]
\centering
\singlespacing
\input{Tabellen/#3}
\caption{#1}
\label{#2}
\end{table}}
\newcommand{\tabelleAnhang}[1] % Parameter: file
{\begin{center}
\singlespacing
\input{Tabellen/#1}
\end{center}}
% einfaches Wechseln der Schrift, z.B.: \changefont{cmss}{sbc}{n}
\newcommand{\changefont}[3]{\fontfamily{#1} \fontseries{#2} \fontshape{#3} \selectfont}
% Verwendung analog zu \includegraphics
\newlength{\myx} % Variable zum Speichern der Bildbreite
\newlength{\myy} % Variable zum Speichern der Bildhöhe
\newcommand\includegraphicstotab[2][\relax]{%
% Abspeichern der Bildabmessungen
\settowidth{\myx}{\includegraphics[{#1}]{#2}}%
\settoheight{\myy}{\includegraphics[{#1}]{#2}}%
% das eigentliche Einfügen
\parbox[c][1.1\myy][c]{\myx}{%
\includegraphics[{#1}]{#2}}%
}
\definecolor{AOBlau}{rgb}{0, 0.28, 0.56}
% verschiedene Befehle um Wörter semantisch auszuzeichnen ----------------------
\newcommand{\Index}[2][\empty]{\ifthenelse{\equal{#1}{\empty}}{\index{#2}#2}{\index{#1}#2}}
\newcommand{\Fachbegriff}[2][\empty]{\ifthenelse{\equal{#1}{\empty}}{\textit{\Index{#2}}}{\textit{\Index[#1]{#2}}}}
\newcommand{\NeuerBegriff}[2][\empty]{\ifthenelse{\equal{#1}{\empty}}{\textbf{\Index{#2}}}{\textbf{\Index[#1]{#2}}}}
\newcommand{\Ausgabe}[1]{\texttt{#1}}
\newcommand{\Eingabe}[1]{\texttt{#1}}
\newcommand{\Code}[1]{\texttt{#1}}
\newcommand{\Datei}[1]{\texttt{#1}}
\newcommand{\Assembly}[1]{\textsf{#1}}
\newcommand{\Klasse}[1]{\textsf{#1}}
\newcommand{\Methode}[1]{\textsf{#1}}
\newcommand{\Attribut}[1]{\textsf{#1}}
\newcommand{\Datentyp}[1]{\textsf{#1}}
\newcommand{\XMLElement}[1]{\textsf{#1}}
\newcommand{\Webservice}[1]{\textsf{#1}}
\newcommand{\Refactoring}[1]{\Fachbegriff{#1}}
\newcommand{\CodeSmell}[1]{\Fachbegriff{#1}}
\newcommand{\Metrik}[1]{\Fachbegriff{#1}}
\newcommand{\DesignPattern}[1]{\Fachbegriff{#1}}

View file

@ -0,0 +1,196 @@
% !TEX root = ../Projektdokumentation.tex
% Anpassung an Landessprache ---------------------------------------------------
\usepackage{babel}
% Umlaute ----------------------------------------------------------------------
% Umlaute/Sonderzeichen wie äüöß direkt im Quelltext verwenden (CodePage).
% Erlaubt automatische Trennung von Worten mit Umlauten.
% ------------------------------------------------------------------------------
\usepackage[T1]{fontenc}
\usepackage{textcomp} % Euro-Zeichen etc.
% Schrift ----------------------------------------------------------------------
\usepackage{lmodern} % bessere Fonts
\usepackage{relsize} % Schriftgröße relativ festlegen
% Tabellen ---------------------------------------------------------------------
\PassOptionsToPackage{table}{xcolor}
\usepackage{tabularx}
% für lange Tabellen
\usepackage{longtable}
\usepackage{array}
\usepackage{ragged2e}
\usepackage{lscape}
\newcolumntype{w}[1]{>{\raggedleft\hspace{0pt}}p{#1}} % Spaltendefinition rechtsbündig mit definierter Breite
% Grafiken ---------------------------------------------------------------------
\usepackage[dvips,final]{graphicx} % Einbinden von JPG-Grafiken ermöglichen
\usepackage{graphics} % keepaspectratio
\usepackage{floatflt} % zum Umfließen von Bildern
\graphicspath{{Bilder/}} % hier liegen die Bilder des Dokuments
% Sonstiges --------------------------------------------------------------------
\usepackage[titles]{tocloft} % Inhaltsverzeichnis DIN 5008 gerecht einrücken
% Explicitly set German titles for ToC, LoF, LoT
\renewcommand{\contentsname}{Inhaltsverzeichnis}
\renewcommand{\listfigurename}{Abbildungsverzeichnis}
\renewcommand{\listtablename}{Tabellenverzeichnis}
\usepackage{amsmath,amsfonts} % Befehle aus AMSTeX für mathematische Symbole
\usepackage{enumitem} % anpassbare Enumerates/Itemizes
\usepackage{xspace} % sorgt dafür, dass Leerzeichen hinter parameterlosen Makros nicht als Makroendezeichen interpretiert werden
\usepackage{makeidx} % für Index-Ausgabe mit \printindex
\usepackage[printonlyused]{acronym} % es werden nur benutzte Definitionen aufgelistet
% Einfache Definition der Zeilenabstände und Seitenränder etc.
\usepackage{setspace}
\usepackage{geometry}
% Symbolverzeichnis
\usepackage[intoc]{nomencl}
\let\abbrev\nomenclature
\renewcommand{\nomname}{Abkürzungsverzeichnis}
\setlength{\nomlabelwidth}{.25\hsize}
\renewcommand{\nomlabel}[1]{#1 \dotfill}
\setlength{\nomitemsep}{-\parsep}
\usepackage{varioref} % Elegantere Verweise. „auf der nächsten Seite“
\usepackage{url} % URL verlinken, lange URLs umbrechen etc.
\usepackage{chngcntr} % fortlaufendes Durchnummerieren der Fußnoten
% \usepackage[perpage]{footmisc} % Alternative: Nummerierung der Fußnoten auf jeder Seite neu
\usepackage{ifthen} % bei der Definition eigener Befehle benötigt
\usepackage{todonotes} % definiert u.a. die Befehle \todo und \listoftodos
\usepackage[square]{natbib} % wichtig für korrekte Zitierweise
% PDF-Optionen -----------------------------------------------------------------
\usepackage{pdfpages}
\pdfminorversion=5 % erlaubt das Einfügen von pdf-Dateien bis Version 1.7, ohne eine Fehlermeldung zu werfen (keine Garantie für fehlerfreies Einbetten!)
\usepackage[
bookmarks,
bookmarksnumbered,
bookmarksopen=true,
bookmarksopenlevel=1,
colorlinks=true,
% diese Farbdefinitionen zeichnen Links im PDF farblich aus
linkcolor=AOBlau, % einfache interne Verknüpfungen
anchorcolor=AOBlau,% Ankertext
citecolor=AOBlau, % Verweise auf Literaturverzeichniseinträge im Text
filecolor=AOBlau, % Verknüpfungen, die lokale Dateien öffnen
menucolor=AOBlau, % Acrobat-Menüpunkte
urlcolor=AOBlau,
% diese Farbdefinitionen sollten für den Druck verwendet werden (alles schwarz)
%linkcolor=black, % einfache interne Verknüpfungen
%anchorcolor=black, % Ankertext
%citecolor=black, % Verweise auf Literaturverzeichniseinträge im Text
%filecolor=black, % Verknüpfungen, die lokale Dateien öffnen
%menucolor=black, % Acrobat-Menüpunkte
%urlcolor=black,
%
%backref, % Quellen werden zurück auf ihre Zitate verlinkt
pdftex,
plainpages=false, % zur korrekten Erstellung der Bookmarks
pdfpagelabels=true, % zur korrekten Erstellung der Bookmarks
hypertexnames=false, % zur korrekten Erstellung der Bookmarks
linktocpage % Seitenzahlen anstatt Text im Inhaltsverzeichnis verlinken
]{hyperref}
% Befehle, die Umlaute ausgeben, führen zu Fehlern, wenn sie hyperref als Optionen übergeben werden
\hypersetup{
pdftitle={\titel -- \untertitel},
pdfauthor={\autorName},
pdfcreator={\autorName},
pdfsubject={\titel -- \untertitel},
pdfkeywords={\titel -- \untertitel},
}
% zum Einbinden von Programmcode -----------------------------------------------
\usepackage{listings}
% Explicitly set German title for LoL
\renewcommand{\lstlistlistingname}{Codeverzeichnis} % For list of listings
\usepackage{xcolor}
\definecolor{hellgelb}{rgb}{1,1,0.9}
\definecolor{colKeys}{rgb}{0,0,1}
\definecolor{colIdentifier}{rgb}{0,0,0}
\definecolor{colComments}{rgb}{0,0.5,0}
\definecolor{colString}{rgb}{1,0,0}
\lstset{
float=hbp,
basicstyle=\footnotesize,
identifierstyle=\color{colIdentifier},
keywordstyle=\color{colKeys},
stringstyle=\color{colString},
commentstyle=\color{colComments},
backgroundcolor=\color{hellgelb},
columns=flexible,
tabsize=2,
frame=single,
extendedchars=true,
showspaces=false,
showstringspaces=false,
numbers=left,
numberstyle=\tiny,
breaklines=true,
breakautoindent=true,
captionpos=b,
}
\lstdefinelanguage{cs}{
sensitive=false,
morecomment=[l]{//},
morecomment=[s]{/*}{*/},
morestring=[b]",
morekeywords={
abstract,event,new,struct,as,explicit,null,switch
base,extern,object,this,bool,false,operator,throw,
break,finally,out,true,byte,fixed,override,try,
case,float,params,typeof,catch,for,private,uint,
char,foreach,protected,ulong,checked,goto,public,unchecked,
class,if,readonly,unsafe,const,implicit,ref,ushort,
continue,in,return,using,decimal,int,sbyte,virtual,
default,interface,sealed,volatile,delegate,internal,short,void,
do,is,sizeof,while,double,lock,stackalloc,
else,long,static,enum,namespace,string},
}
\lstdefinelanguage{natural}{
sensitive=false,
morecomment=[l]{/*},
morestring=[b]",
morestring=[b]',
alsodigit={-,*},
morekeywords={
DEFINE,DATA,LOCAL,END-DEFINE,WRITE,CALLNAT,PARAMETER,USING,
IF,NOT,END-IF,ON,*ERROR-NR,ERROR,END-ERROR,ESCAPE,ROUTINE,
PERFORM,SUBROUTINE,END-SUBROUTINE,CONST,END-FOR,END,FOR,RESIZE,
ARRAY,TO,BY,VALUE,RESET,COMPRESS,INTO,EQ},
}
\lstdefinelanguage{php}{
sensitive=false,
morecomment=[l]{/*},
morestring=[b]",
morestring=[b]',
alsodigit={-,*},
morekeywords={
abstract,and,array,as,break,case,catch,cfunction,class,clone,const,
continue,declare,default,do,else,elseif,enddeclare,endfor,endforeach,
endif,endswitch,endwhile,extends,final,for,foreach,function,global,
goto,if,implements,interface,instanceof,namespace,new,old_function,or,
private,protected,public,static,switch,throw,try,use,var,while,xor
die,echo,empty,exit,eval,include,include_once,isset,list,require,
require_once,return,print,unset},
}
\lstdefinelanguage{json}{
basicstyle=\ttfamily\small,
showstringspaces=false,
breaklines=true,
commentstyle=\color{green!50!black},
stringstyle=\color{red},
keywords={true, false, null},
keywordstyle=\color{blue}\bfseries,
morestring=[s]{"}{"},
morecomment=[l]{//},
morecomment=[s]{/*}{*/},
}

View file

@ -0,0 +1,83 @@
% !TEX root = ../Projektdokumentation.tex
% Seitenränder -----------------------------------------------------------------
\setlength{\topskip}{\ht\strutbox} % behebt Warnung von geometry
\geometry{a4paper,left=25mm,right=25mm,top=33mm,bottom=33mm,head=53.14769pt}
\deffootnote{1em}{1em}{\textsuperscript{\thefootnotemark}\fontsize{9pt}{11pt}\selectfont}
\usepackage[
automark, % Kapitelangaben in Kopfzeile automatisch erstellen
headsepline, % Trennlinie unter Kopfzeile
ilines % Trennlinie linksbündig ausrichten
]{scrlayer-scrpage}
% Kopf- und Fußzeilen ----------------------------------------------------------
\pagestyle{scrheadings}
% chapterpagestyle gibt es nicht in scrartcl
%\renewcommand{\chapterpagestyle}{scrheadings}
\clearpairofpagestyles
% Kopfzeile
\renewcommand{\headfont}{\normalfont} % Schriftform der Kopfzeile
\ihead{\large{\textsc{\titel}}\\ \small{\untertitel} \\[2ex] \textit{\headmark}}
\chead{}
\ohead{\includegraphics[scale=0.09]{\betriebLogo}}
%\setheadwidth[0pt]{textwithmarginpar} % Kopfzeile über den Text hinaus verbreitern (falls Logo den Text überdeckt)
% Fußzeile
\cfoot{}
\ofoot{\pagemark}
% Überschriften nach DIN 5008 in einer Fluchtlinie
% ------------------------------------------------------------------------------
% Abstand zwischen Nummerierung und Überschrift definieren
% > Schön wäre hier die dynamische Berechnung des Abstandes in Abhängigkeit
% > der Verschachtelungstiefe des Inhaltsverzeichnisses
\newcommand{\headingSpace}{1.5cm}
% Abschnittsüberschriften im selben Stil wie beim Inhaltsverzeichnis einrücken
\renewcommand*{\othersectionlevelsformat}[3]{
\makebox[\headingSpace][l]{#3\autodot}
}
% Für die Einrückung wird das Paket tocloft benötigt
%\cftsetindents{chapter}{0.0cm}{\headingSpace}
\cftsetindents{section}{0.0cm}{\headingSpace}
\cftsetindents{subsection}{0.0cm}{\headingSpace}
\cftsetindents{subsubsection}{0.0cm}{\headingSpace}
\cftsetindents{figure}{0.0cm}{\headingSpace}
\cftsetindents{table}{0.0cm}{\headingSpace}
% Allgemeines
% ------------------------------------------------------------------------------
\setstretch{1.15} % Zeilenabstand 1.15 Zeilen
\frenchspacing % erzeugt ein wenig mehr Platz hinter einem Punkt
\renewcommand{\rmdefault}{phv} % Arial als Std Schriftart
\renewcommand{\sfdefault}{phv}
% Schusterjungen und Hurenkinder vermeiden
\clubpenalty = 10000
\widowpenalty = 10000
\displaywidowpenalty = 10000
% Quellcode-Ausgabe formatieren
\lstset{numbers=left, numberstyle=\tiny, numbersep=5pt, breaklines=true}
\lstset{emph={square}, emphstyle=\color{red}, emph={[2]root,base}, emphstyle={[2]\color{blue}}}
\counterwithout{footnote}{section} % Fußnoten fortlaufend durchnummerieren
\setcounter{tocdepth}{3} % im Inhaltsverzeichnis werden die Kapitel bis zum Level der subsubsection übernommen
\setcounter{secnumdepth}{3} % Kapitel bis zum Level der subsubsection werden nummeriert
% Aufzählungen anpassen
\renewcommand{\labelenumi}{\arabic{enumi}.}
\renewcommand{\labelenumii}{\arabic{enumi}.\arabic{enumii}.}
\renewcommand{\labelenumiii}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}}
% Tabellenfärbung:
\definecolor{heading}{rgb}{0.64,0.78,0.86}
\definecolor{odd}{rgb}{0.9,0.9,0.9}

View file

@ -0,0 +1,3 @@
% Trennvorschläge im Text werden mit \" angegeben
% untrennbare Wörter und Ausnahmen von der normalen Trennung können in dieser
% Datei mittels \hyphenation definiert werden

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,78 @@
% !TEX root = Projektdokumentation.tex
\section{Anhang}
\subsection{Detaillierte Zeitplanung}
\label{app:Zeitplanung}
\tabelleAnhang{ZeitplanungKomplett}
\input{Anhang/AnhangLastenheft.tex}
\clearpage
\input{Anhang/AnhangRessourcen.tex}
\clearpage
\subsection{Use Case-Diagramm}
\label{app:UseCase}
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{UseCase.pdf}{1.3}
\caption{Use Case-Diagramm}
\end{figure}
\clearpage
\subsection{Amortisation}
\label{app:Amortisation}
Der Zeitpunkt der Amortisation wird als Schnittpunkt der beiden Geraden angegeben.
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{amortisationgrafik.png}{1}
\caption{Grafische Darstellung der Amortisation}
\end{figure}
\clearpage
\subsection{composer.json Konfiguration für neusta-m2-intex-client}
\label{app:ComposerJson}
\lstinputlisting[language=json, caption={Konfiguration für neusta-m2-intex-client}]{Listings/composer.json}
\clearpage
\subsection{Deklaration zur Anlage einer SQL Tabelle im Magento 2 Umfeld}
\label{app:InstallData}
\lstinputlisting[language=xml, caption={Deklaration zur Anlage einer SQL Tabelle im Magento 2 Umfeld}]{Listings/InstallData.xml}
\clearpage
\subsection{Klasse: Factory}
\label{app:Factory}
\lstinputlisting[language=php, caption={Klasse: Factory}]{Listings/Factory.php}
\clearpage
\subsection{Klasse: CustomerConnection}
\label{app:CustomerConnection}
\lstinputlisting[language=php, caption={Klasse: CustomerConnection}]{Listings/CustomerConnection.php}
\clearpage
\subsection{Klasse: Connection}
\label{app:Connection}
\lstinputlisting[language=php, caption={Abstrakte Klasse: Connection}]{Listings/Connection.php}
\clearpage
\subsection{Klasse: CustomerDataController}
\label{app:CustomerDataController}
\lstinputlisting[language=php, caption={Klasse: CustomerDataController}]{Listings/CustomerDataController.php}
\clearpage
\subsection{UnitTest: FactoryTest}
\label{app:UnitTest}
\lstinputlisting[language=php, caption={Unit Test der Klasse: Factory}]{Listings/UnitTest.php}
\clearpage

View file

@ -0,0 +1,15 @@
\subsection{Benutzerdokumentation}
\label{app:BenutzerDoku}
Ausschnitt aus der Benutzerdokumentation:
\begin{table}[htb]
\begin{tabularx}{\textwidth}{cXX}
\rowcolor{heading}\textbf{Symbol} & \textbf{Bedeutung global} & \textbf{Bedeutung einzeln} \\
\includegraphicstotab[]{weather-clear.png} & Alle Module weisen den gleichen Stand auf. & Das Modul ist auf dem gleichen Stand wie das Modul auf der vorherigen Umgebung. \\
\rowcolor{odd}\includegraphicstotab[]{weather-clear-night.png} & Es existieren keine Module (fachlich nicht möglich). & Weder auf der aktuellen noch auf der vorherigen Umgebung sind Module angelegt. Es kann also auch nichts übertragen werden. \\
\includegraphicstotab[]{weather-few-clouds-night.png} & Ein Modul muss durch das Übertragen von der vorherigen Umgebung erstellt werden. & Das Modul der vorherigen Umgebung kann übertragen werden, auf dieser Umgebung ist noch kein Modul vorhanden. \\
\rowcolor{odd}\includegraphicstotab[]{weather-few-clouds.png} & Auf einer vorherigen Umgebung gibt es ein Modul, welches übertragen werden kann, um das nächste zu aktualisieren. & Das Modul der vorherigen Umgebung kann übertragen werden um dieses zu aktualisieren. \\
\includegraphicstotab[]{weather-storm.png} & Ein Modul auf einer Umgebung wurde entgegen des Entwicklungsprozesses gespeichert. & Das aktuelle Modul ist neuer als das Modul auf der vorherigen Umgebung oder die vorherige Umgebung wurde übersprungen. \\
\end{tabularx}
\end{table}

View file

@ -0,0 +1,7 @@
\subsection{Entwicklerdokumentation}
\label{app:Doc}
\begin{center}
\includegraphics[page=1, width=0.9\textwidth]{doc.pdf}
\includegraphics[page=2, width=0.9\textwidth]{doc.pdf}
\end{center}

View file

@ -0,0 +1,19 @@
\subsection{Oberflächenentwürfe}
\label{app:Entwuerfe}
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{MockupModules.pdf}{0.7}
\caption{Liste der Module mit Filtermöglichkeiten}
\end{figure}
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{MockupModul.pdf}{0.7}
\caption{Anzeige der Übersichtsseite einzelner Module}
\end{figure}
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{MockupTag.pdf}{0.7}
\caption{Anzeige und Filterung der Module nach Tags}
\end{figure}

View file

@ -0,0 +1,22 @@
\subsection{Lastenheft (Auszug)}
\label{app:Lastenheft}
Im folgenden Auszug des Lastenheftes werden die Anforderungen definiert, die an die neu entwickelte Anwendung gestellt werden.
Die Anwendung muss folgende Anforderungen erfüllen:
\begin{enumerate}[itemsep=0em,partopsep=0em,parsep=0em,topsep=0em]
\item Verarbeitung der empfangenen Daten von \ac{IX}
\begin{enumerate}
\item Die Anwendung muss Produkt- und Nutzerdaten von der \ac{IX}-\ac{API} abrufen können.
\item Die geholten Daten sollen temporär zwischengespeichert werden, um den Import zu \ac{M2} von der Datenbeschaffung abzukapseln
\item Die gespeicherten Daten werden getrennt von der \ac{IX}-\ac{API} an die \ac{M2} Import-Funktionen gegeben und so in das \ac{M2} System integriert
\end{enumerate}
\item Sonstige Anforderungen
\begin{enumerate}
\item Die Anwendung muss ohne das Installieren einer zusätzlichen Software über das Terminal erreichbar sein.
\item Die Import der Daten muss jede Nacht \bzw nach jedem Fehlschlag automatisch aktualisiert werden.
\item Die Anwendung soll jederzeit erreichbar sein.
\item Da sich die Entwickler auf die Anwendung verlassen, muss diese korrekte Daten liefern und darf keinen Interpretationsspielraum lassen.
\item Die Anwendung muss so flexibel sein, dass sie bei Änderungen im Entwicklungsprozess einfach angepasst werden kann.
\end{enumerate}
\end{enumerate}

View file

@ -0,0 +1,52 @@
\subsection{Pflichtenheft (Auszug)}
\label{app:Pflichtenheft}
\subsubsection*{Zielbestimmung}
\begin{enumerate}[itemsep=0em,partopsep=0em,parsep=0em,topsep=0em]
\item Musskriterien % Wikipedia: für das Produkt unabdingbare Leistungen, die in jedem Fall erfüllt werden müssen
\begin{enumerate}
\item Modul-Liste: Zeigt eine filterbare Liste der Module mit den dazugehörigen Kerninformationen sowie Symbolen zur Einhaltung des Entwicklungsprozesses an
\begin{itemize}
\item In der Liste wird der Name, die Bibliothek und Daten zum Source und Kompilat eines Moduls angezeigt.
\item Ebenfalls wird der Status des Moduls hinsichtlich Source und Kompilat angezeigt. Dazu gibt es unterschiedliche Status-Zeichen, welche symbolisieren in wie weit der Entwicklungsprozess eingehalten wurde \bzw welche Schritte als nächstes getan werden müssen. So gibt es \zB Zeichen für das Einhalten oder Verletzen des Prozesses oder den Hinweis auf den nächsten zu tätigenden Schritt.
\item Weiterhin werden die Benutzer und Zeitpunkte der aktuellen Version der Sourcen und Kompilate angezeigt. Dazu kann vorher ausgewählt werden, von welcher Umgebung diese Daten gelesen werden sollen.
\item Es kann eine Filterung nach allen angezeigten Daten vorgenommen werden. Die Daten zu den Sourcen sind historisiert. Durch die Filterung ist es möglich, auch Module zu finden, die in der Zwischenzeit schon von einem anderen Benutzer editiert wurden.
\end{itemize}
\item Tag-Liste: Bietet die Möglichkeit die Module anhand von Tags zu filtern.
\begin{itemize}
\item Es sollen die Tags angezeigt werden, nach denen bereits gefiltert wird und die, die noch der Filterung hinzugefügt werden könnten, ohne dass die Ergebnisliste leer wird.
\item Zusätzlich sollen die Module angezeigt werden, die den Filterkriterien entsprechen. Sollten die Filterkriterien leer sein, werden nur die Module angezeigt, welche mit einem Tag versehen sind.
\end{itemize}
\item Import der Moduldaten aus einer bereitgestellten \acs{CSV}-Datei
\begin{itemize}
\item Es wird täglich eine Datei mit den Daten der aktuellen Module erstellt. Diese Datei wird (durch einen Cronjob) automatisch nachts importiert.
\item Dabei wird für jedes importierte Modul ein Zeitstempel aktualisiert, damit festgestellt werden kann, wenn ein Modul gelöscht wurde.
\item Die Datei enthält die Namen der Umgebung, der Bibliothek und des Moduls, den Programmtyp, den Benutzer und Zeitpunkt des Sourcecodes sowie des Kompilats und den Hash des Sourcecodes.
\item Sollte sich ein Modul verändert haben, werden die entsprechenden Daten in der Datenbank aktualisiert. Die Veränderungen am Source werden dabei aber nicht ersetzt, sondern historisiert.
\end{itemize}
\item Import der Informationen aus \ac{SVN}. Durch einen \gqq{post-commit-hook} wird nach jedem Einchecken eines Moduls ein \acs{PHP}-Script auf der Konsole aufgerufen, welches die Informationen, die vom \ac{SVN}-Kommandozeilentool geliefert werden, an \acs{NatInfo} übergibt.
\item Parsen der Sourcen
\begin{itemize}
\item Die Sourcen der Entwicklungsumgebung werden nach Tags, Links zu Artikeln im Wiki und Programmbeschreibungen durchsucht.
\item Diese Daten werden dann entsprechend angelegt, aktualisiert oder nicht mehr gesetzte Tags/Wikiartikel entfernt.
\end{itemize}
\item Sonstiges
\begin{itemize}
\item Das Programm läuft als Webanwendung im Intranet.
\item Die Anwendung soll möglichst leicht erweiterbar sein und auch von anderen Entwicklungsprozessen ausgehen können.
\item Eine Konfiguration soll möglichst in zentralen Konfigurationsdateien erfolgen.
\end{itemize}
\end{enumerate}
\end{enumerate}
\subsubsection*{Produkteinsatz}
\begin{enumerate}[itemsep=0em,partopsep=0em,parsep=0em,topsep=0em]
\item{Anwendungsbereiche\\
Die Webanwendung dient als Anlaufstelle für die Entwicklung. Dort sind alle Informationen für die Module an einer Stelle gesammelt. Vorher getrennte Anwendungen werden ersetzt \bzw verlinkt.}
\item{Zielgruppen\\
\NI wird lediglich von den \ac{Natural}-Entwicklern in der EDV-Abteilung genutzt.}
\item{Betriebsbedingungen\\ % Wikipedia: physikalische Umgebung des Systems, tägliche Betriebszeit, ständige Beobachtung des Systems durch Bediener oder unbeaufsichtigter Betrieb
Die nötigen Betriebsbedingungen, also der Webserver, die Datenbank, die Versionsverwaltung, das Wiki und der nächtliche Export sind bereits vorhanden und konfiguriert. Durch einen täglichen Cronjob werden entsprechende Daten aktualisiert, die Webanwendung ist jederzeit aus dem Intranet heraus erreichbar.}
\end{enumerate}

View file

@ -0,0 +1,28 @@
\subsection{Verwendete Ressourcen}
\label{app:Ressourcen}
Hardware
\begin{itemize}
\item Büroarbeitsplatz (Schreibtisch, ergonomischer Stuhl)
\item Fujitsu Lifebook U-Series - Notebook
\item Peripheriegeräte für Notebook (Tastatur, Maus)
\end{itemize}
Software
\begin{itemize}
\item Debian Derivat Ubuntu 18.04 - Betriebssystem
\item JetBrains PHPStorm - Entwicklungsumgebung \ac{PHP}
\item git - Verteilte Versionsverwaltung
\item Docker - Open Source Management von virtuellen Maschinen (Containerbasiert)
\item mySQL - Open Source relationelles Datenbank Management System
\item Composer - Open Source Package Management System auf Anwendungsebene für \ac{PHP}
\item Magento 2 Community Edition - Open Source \ac{eCommerce} Platform
\item TeXify IDEA - Open Source Plugin für PHPStorm als Distribution des Textsatzsystems TeX
\item PHPUnit - Framework zur Durchführung von Unit-Tests
\item LaTeX-Vorlage zur IHK-Projektdokumentation für Fachinformatiker Anwendungsentwicklung von Stefan Macke - \url{http://fiae.link/LaTeXVorlageFIAE}
\end{itemize}
Personal
\begin{itemize}
\item Mitarbeiter Softwareentwicklung der \ac{NSD} - Festlegung der Anforderungen, Abnahme des Projektes \& Review des Codes
\item Auszubildender Fachinformatiker als Entwickler - Umsetzung des Projektes
\end{itemize}

View file

@ -0,0 +1,14 @@
\subsection{Screenshots der Anwendung}
\label{Screenshots}
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{tagliste.pdf}{1}
\caption{Anzeige und Filterung der Module nach Tags}
\end{figure}
\clearpage
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{modulliste.pdf}{1}
\caption{Liste der Module mit Filtermöglichkeiten}
\end{figure}
\clearpage

View file

@ -0,0 +1,9 @@
\subsection{Testfall und sein Aufruf auf der Konsole}
\label{app:Test}
\lstinputlisting[language=php, caption={Testfall in PHP}]{Listings/tests.php}
\clearpage
\begin{figure}[htb]
\centering
\includegraphicsKeepAspectRatio{testcase.jpg}{1}
\caption{Aufruf des Testfalls auf der Konsole}
\end{figure}

View file

@ -0,0 +1,4 @@
% Abkürzungen
\newcommand{\Versis}{\textsc{Versis}\xspace}
\newcommand{\NI}{NatInfo\xspace}
\newcommand{\AO}{\textsc{Alte Oldenburger} Krankenversicherung\xspace}

View file

@ -0,0 +1,92 @@
% This file was created with JabRef 2.4.2.
% Encoding: UTF8
@book{Rohrer2011,
address = {Solingen},
edition = {5.},
title = {Clevere Tipps für die Projektarbeit - {IT-Berufe:} Abschlussprüfung Teil A},
isbn = {3882347538},
url = {http://fiae.link/ClevereTippsFuerDieProjektarbeit},
publisher = {{U-Form-Verlag}},
author = {Rohrer, Anselm and Sedlacek, Ramona},
year = {2011}
}
@misc{Bundesgesetzblatt48,
title = {Verordnung über die Berufsausbildung im Bereich der Informations- und Telekommunikationstechnik},
url = {http://fiae.link/VerordnungITBerufe},
author = {{Regierung der Bundesrepublik Deutschland}},
month = jul,
year = {1997},
pages = {1741--1799}
}
@techreport{BMBF2000,
address = {Bonn},
type = {Abschlussbericht},
title = {Umsetzungshilfen für die neue Prüfungsstruktur der {IT-Berufe}},
shorttitle = {{BMBF2000}},
url = {http://fiae.link/UmsetzungshilfenITBerufe},
author = {{Bundesministerium für Bildung und Forschung}},
institution = {{Bundesministerium für Bildung und Forschung}},
month = jul,
year = {2000},
pages = {476}
}
@techreport{Grashorn2010,
address = {Vechta},
type = {Dokumentation zur Projektarbeit},
title = {Entwicklung von NatInfo -- Webbasiertes Tool zur Unterstützung der Entwickler},
author = {Dirk Grashorn},
institution = {{Alte Oldenburger Krankenversicherung AG}},
month = apr,
year = {2010},
}
@misc{MerkblattIHK,
address = {Oldenburg},
title = {Merkblatt zur Abschlussprüfung der IT-Berufe},
author = {{IHK Oldenburg}},
institution = {{Oldenburgische Industrie- und Handelskammer}},
month = may,
year = {2006},
url = {http://fiae.link/MerkblattDokuOldenburg},
}
@misc{BewertungsmatrikIHK,
address = {Darmstadt},
title = {Bewertungsmatrix für Fachinformatiker/innen Anwendungsentwicklung},
author = {{IHK Darmstadt}},
institution = {{IHK Darmstadt Rhein Main Neckar}},
month = mar,
year = {2011},
url = {http://fiae.link/BewertungsmatrixDokuDarmstadt},
}
@misc{ISO9126,
title = {{Software-Engineering} Qualität von {Software-Produkten} Teil 1: Qualitätsmodell},
author = {{ISO/IEC 9126-1}},
month = jun,
year = {2001}
}
@BOOKLET{phpDoc,
title = {{phpDocumentor-Website}},
author = {{phpdoc.org}},
lastchecked = {20.04.2010},
year = {2010},
owner = {grashorn},
timestamp = {2010.04.22},
url = {http://www.phpdoc.org/}
}
@BOOKLET{Symfony,
title = {Symfony - Open-Source PHP Web Framework},
author = {{Sensio Labs}},
lastchecked = {20.04.2010},
year = {2010},
owner = {grashorn},
timestamp = {2010.04.22},
url = {http://www.symfony-project.org/}
}

View file

@ -0,0 +1,68 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœm“MŽ1 …÷9EÖ,L;Çਤ™Y àþÏŽSÝ ¨¥ê|ñOÞsª~¦’í÷ë=ý^òûïT•®Ü˜™‰kË­ÐÔ‰<YÔÊ¢6jkæ KäèðgG„Jáœî¥]V6$<08>y­¨
¸»{>Úì:×}}ÉXw„ûôuÑü¬ÿÊî§ö¬<C3B6>f1GÝêæ¶ûð‰ÆA<>=HÌMløïÝnéÁ,4ÍÁ.UmÏú¦M×Ι´ç<e=Ñ«Œf)M«Q™ùÕØÿ¬¾¥º\…LÒfÞÑ Œ\ulÒh|4aÂ8­5\A„Ù%ŸÒ ï{ÔBºÆ©ÔŠAËÃûÆë{Â[Ò)}Öë–^ ¼}I8kà<6B>XTðBº%=ôÁfA®Ö8ÅF bCS«6{cŒYÌ;áX©ÔÙ7«v GPj7ŠƒÑC_ 'ôôÚ]ÆVw¢L #HlCŸã[ˆ(&45Nàå•÷ñ Š«yF<79><46>t£6ÆoÛA1ôŠ.Â|ß#üøûp%ßÒ<>Ò'
endstream
endobj
4 0 obj
414
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 51.200001 51.200001 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.10.2 (http://cairographics.org))
/Producer (cairo 1.10.2 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000812 00000 n
0000000528 00000 n
0000000015 00000 n
0000000506 00000 n
0000000600 00000 n
0000000877 00000 n
0000001004 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1056
%%EOF

Binary file not shown.

View file

@ -0,0 +1,68 @@
%PDF-1.5
%µí®û
3 0 obj
<< /Length 4 0 R
/Filter /FlateDecode
>>
stream
xœmRIŽÜ0 ¼ëz#nZž'fæ09$ù?<3F>"¥v÷<04>[%eY¿J«ñü~¯ß~´úþ§ˆÑ²U<C2B2>IêÏÊL,^½Ñ´‰<]ämá N¾f½pDŽ<44>|wD¨5®áÞä +ʆf^ëTœù ÙuÙËaÌóHǺ#ÜgžÕ×þ¯úz¤Wë4[(Šl—<6C>}óð#zþqÚ¤¡æ\ä‡÷í<C3B7>îÖ
nyÁ[6ºvÎ<ÁxÏGÙO΄àjÃ#Åue7¦³~ö?©o…<6F>lAÆ8,Ö)ÙÕÁŸ• ŒB^X„°í;,<2C>ÌÛ|¹˜fU´(S4¢Fb@=NM,ÖÓ‰a“Àvls‡Ÿ;YA*ó<>Á³ÂeçhøsxÅ¢©÷htö*8.7o hºBŒÏžá4át /jÚ! ü!•i ˜+ ÛŒÉ8µpµC鈪ÿóSSp´76Ó5ázævñß5otK8%ŽÈÊ~×!âƒÒåËÇuô&‰¦%¡è#V2ÙÆ¾èù?“þRª˜ã“¸a¬3°,Ll»¤h§æ«~5Më_½•ïå/ÅÏÕ
endstream
endobj
4 0 obj
447
endobj
2 0 obj
<<
/ExtGState <<
/a0 << /CA 1 /ca 1 >>
>>
>>
endobj
5 0 obj
<< /Type /Page
/Parent 1 0 R
/MediaBox [ 0 0 51.200001 51.200001 ]
/Contents 3 0 R
/Group <<
/Type /Group
/S /Transparency
/CS /DeviceRGB
>>
/Resources 2 0 R
>>
endobj
1 0 obj
<< /Type /Pages
/Kids [ 5 0 R ]
/Count 1
>>
endobj
6 0 obj
<< /Creator (cairo 1.10.2 (http://cairographics.org))
/Producer (cairo 1.10.2 (http://cairographics.org))
>>
endobj
7 0 obj
<< /Type /Catalog
/Pages 1 0 R
>>
endobj
xref
0 8
0000000000 65535 f
0000000845 00000 n
0000000561 00000 n
0000000015 00000 n
0000000539 00000 n
0000000633 00000 n
0000000910 00000 n
0000001037 00000 n
trailer
<< /Size 8
/Root 7 0 R
/Info 6 0 R
>>
startxref
1089
%%EOF

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 347 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,27 @@
% !TEX root = Projektdokumentation.tex
\begin{titlepage}
\begin{center}
\includegraphics[scale=0.25]{hitec-logo.png}\\[1ex]
\Large{\ausbildungsberuf}\\
\LARGE{\betreff}\\[4ex]
\huge{\textbf{\titel}}\\[1.5ex]
\Large{\textbf{\untertitel}}\\[4ex]
\normalsize
Projektzeitraum: \projektZeitraum\\[3em]
\textbf{Projektteilnehmer:}\\
Constantin Simonis\\
Phan Huy Tran\\
Jan-Marlon Leibl\\
Jan Klattenhoff\\
Lea Ziemke\\
\textbf{Projektaufsicht:}\\
Katrin Deeken\\
Bernd Heidemann\\
\end{center}
\end{titlepage}

View file

@ -0,0 +1,12 @@
% !TEX root = Projektdokumentation.tex
\input{Inhalt/Einleitung}
\input{Inhalt/Projektarchitektur}
\input{Inhalt/CI}
\input{Inhalt/Auth.tex}
\input{Inhalt/Dice.tex}
\input{Inhalt/Slots.tex}
\input{Inhalt/Coinflip.tex}
\input{Inhalt/Blackjack.tex}
\input{Inhalt/Lootboxes.tex}
\input{Inhalt/Deployment.tex}

View file

@ -0,0 +1,11 @@
% !TEX root = ../Projektdokumentation.tex
\section{Abnahmephase}
\label{sec:Abnahmephase}
Die Anwendung wurde gemäß der in Abschnitt~\ref{sec:Entwicklungsprozess}: \nameref{sec:Entwicklungsprozess} agilen Entwicklung stetig von Mitarbeitern der \ac{NSD}
per Code Review abgenommen. Die Code Review erfolgte über das webbasierte Development Operations Lebenszyklus Tool GitLab \footnote{GitLab - \url{https://gitlab.com}}, in dessen Repository die Anwendung per git \footnote{git - \url{https://git-scm.com/}}
versioniert wurde. Sofern ein neues Feature vom Autor fertiggestellt wurde, erstellte der Autor einen sogenannten Merge Request in GitLab. Dieser Merge Request hat zur Folge,
dass ein zugeteilter Mitarbeiter der \ac{NSD} den Code freigeben muss und dieser dann erst in den Quellcode der Anwendung übernommen werden kann.
Teil der Abnahmebedingungen war, dass der zu implementierende Code sinnvoll mit Unit Tests abgedeckt ist. Exemplarisch hierfür steht der \Anhang{app:UnitTest}, welcher
einen beispielhaften Unit Test für die Komponente neusta-m2-intex-client-config zeigt.

View file

@ -0,0 +1,105 @@
% !TEX root = ../Projektdokumentation.tex
\section{Analysephase}
\label{sec:Analysephase}
\subsection{Ist-Analyse}
\label{sec:IstAnalyse}
Ein Direktimport über Schnittstellen wird für \ac{M2} nicht zur Verfügung gestellt.
Derzeit werden solche Importer per Modul für jeden Webshop individuell selbst entwickelt und angepasst.
Als Modul bezeichnet man im \ac{M2} Umfeld eine Erweiterung des Frameworks durch neue Funktionalitäten.
Die hierfür neu entwickelnden Module stellen \acs{API}-Abfragen an \ac{IX} und importieren die Daten ohne temporäres Zwischenspeichern in \ac{M2}.
Vorhandene Fehlerquellen sind hier die benötigte Verbindung zur \ac{IX}-\acs{API} und die unbedingte Richtigkeit der übertragenen Daten.
Kommen Fehler beim Import aufgrund von fehlender oder unvollständiger Datensätze zustande, bricht der komplette Import ab.
Gleiches gilt für die Export Funktionen zum Exportieren von Bestellungen von \ac{M2} zu \ac{IX}.
\subsection{Wirtschaftlichkeitsanalyse}
\label{sec:Wirtschaftlichkeitsanalyse}
Aufgrund des in den Abschnitten~\ref{sec:Projektbegruendung}: \nameref{sec:Projektbegruendung} und~\ref{sec:IstAnalyse}: \nameref{sec:IstAnalyse}
geschilderten und erläuterten derzeitigen Zustandes von Import/Export-Modulen in Abhängigkeit zum \ac{CRM} \ac{IX} für \ac{M2}, ist die Umsetzung
des Projektes unbedingt erforderlich. Eine gerechtfertigte Realisierung aus wirtschaftlichen Gesichtspunkten wird in den folgenden Abschnitten analysiert.
\subsubsection{\gqq{Make or Buy}-Entscheidung}
\label{sec:MakeOrBuyEntscheidung}
Bei dem Projekt handelt es sich um die Erfüllung von kundenspezifischen Anforderungen, sofern \ac{IX} als \ac{CRM} genutzt wird.
Hierfür lässt sich auf dem Markt keine Lösung finden, die eine Integration der Warenwirtschaft in ein \ac{M2} ermöglicht.
Daher soll das Projekt in Eigenentwicklung durchgeführt und durch Nutzung von Open Source Anwendungen erweitert werden.
\subsubsection{Projektkosten}
\label{sec:Projektkosten}
Im folgenden sollen die Kosten kalkuliert werden, die während der Entwicklung des Projektes anfallen. Neben Personalkosten, die durch die Umsetzung
des Projektes verursacht werden, mussten auch Aufwendungen für die in Abschnitt~\ref{sec:Ressourcenplanung}: \nameref{sec:Ressourcenplanung} genannten Ressourcen
berücksichtigt werden. Da Personalkosten im Original nicht herausgegeben werden dürfen, erfolgte die Kalkulation anhand von unterstellten Werten.
Die Durchführungszeit des Projekts beträgt 70 Stunden.
Unterstellt wurde ein Stundensatz in Höhe von \eur{10} für Auszubildende sowie \eur{25} für Mitarbeiter.
Für die o.g. Ressourcennutzung wurde ein pauschaler Satz von \eur{15} angenommen.
Eine Aufstellung der Kosten lassen sich der Tabelle~\ref{tab:Kostenaufstellung} entnehmen und betragen insgesamt \eur{2910}.
\tabelle{Kostenaufstellung}{tab:Kostenaufstellung}{Kostenaufstellung.tex}
\subsubsection{Amortisationsdauer}
\label{sec:Amortisationsdauer}
Der folgende Abschnitt dient zur Ermittlung des Zeitpunktes, ab welchem sich die Entwicklung der Anwendung amortisiert hat.
Anhand dieses Wertes kann beurteilt werden, ob die Umsetzung des Projektes aus wirtschaftlicher Sicht sinnvoll ist und sich hieraus
Kostenvorteile ergeben.
Nachfolgend soll nun die Amortisationsdauer berechnet werden. Diese gibt an, ab welchem Zeitpunkt die Anschaffungs- und Entwicklungskosten durch die
Zeitersparnis beglichen werden kann.
\tabelle{Zeitersparnis}{tab:Zeitersparnis}{Zeitersparnis} \\
\textbf{Berechnung der Amortisationsdauer:}
\begin{align}
415\ \frac{min}{Monat} \cdot 12\ \frac{Monate}{Jahr} = 4980\ \frac{min}{Jahr} = 83\ \frac{h}{Jahr}
\end{align}
\begin{align}
83\ \frac{h}{Jahr} \cdot (\eur{25} + \eur{15}) = 3320\ \frac{\eur{}}{Jahr}
\end{align}
\begin{align}
\frac{\eur{3320}}{2910 \frac{\eur{}}{Jahr}} = 1,14\ Jahre \approx 1\ Jahr\ \&\ 1,5\ Monate
\end{align}
Zusätzlich wurde die Amortisation grafisch dargestellt. Das Diagramm enthält die variablen Kosten (pro Jahr) der neuen Lösung sowie die Kosten,
die für die Entwicklung der neuen Umsetzung angefallen sind. Die Grafik findet sich im~\Anhang{app:Amortisation}.
Anhand der Amortisationsrechnung ergibt sich für das Projekt eine Amortisationsdauer von einem Jahr und ca. eineinhalb Monaten. Dies definiert den Zeitraum, über den
die neue Anwendung mindestens eingesetzt werden muss, um Anschaffungskosten und Kosteneinsparung auszugleichen. Da das Projekt von der \ac{NSD} langfristig eingesetzt
werden soll, kann das Projekt unter wirtschaftlichen Gesichtspunkten als sinnvoll eingestuft werden.
\subsection{Nutzwertanalyse}
\label{sec:Nutzwertanalyse}
Durch die in den Abschnitten~\ref{sec:Projektkosten}: \nameref{sec:Projektkosten} und~\ref{sec:Amortisationsdauer}: \nameref{sec:Amortisationsdauer} aufgeführten Ergebnisse wird die Realisierung
des Projektes bereits ausreichend gerechtfertigt. Hierdurch soll an dieser Stelle auf eine detaillierte Analyse nicht-monetärer Vorteile verzichtet werden.
Nicht-monetäre Vorteile der Anwendung wären aber \zB die angenehmere Wartbarkeit durch bessere Übersicht der neu implementierten Modulstruktur sowie die Implementierung von aussagekräftigeren Fehlermeldungen
und der Möglichkeit, die Anwendung schnell für individuelle Wünsche anzupassen.
\subsection{Anwendungsfälle}
\label{sec:Anwendungsfaelle}
Eine grobe Übersicht über die von der Anwendung abzudeckenden Anwendungsfälle wurde im Laufe der Analysephase per Use-Case-Diagramm dargestellt.
Dieses Diagramm befindet sich im \Anhang{app:UseCase} und bildet alle Funktionen ab, welche aus Anwendersicht benötigt werden.
Dem Entwickler stehen der Vollimport sowie die Teilimporte der Daten für Nutzer- und Produktdaten zur Verfügung. Die Teilimporte sind erforderlich,
um mögliche Fehlimporte im Kleinen neu anstoßen zu können und so einen erneuten Vollimport zu verhindern.
Beim Auslösen des Import-Vorgangs werden die Daten von der \ac{IX}-\acs{API} angefordert und zwischengespeichert, um abermalige Requests zu verhindern.
Die zwischengespeicherten Daten werden dann zu \ac{M2} importiert und dem Webshop zur Verfügung gestellt.
Der Vorgang des Vollimports wird außerdem auch über einen \acs{CRON}-Job in geplanten Zeitabständen zur Verfügung gestellt, um ein abermaliges, manuelles
Anstoßen zu umgehen.
\subsection{Qualitätsanforderungen}
\label{sec:Qualitaetsanforderungen}
Die Anwendung soll unter Green Development \footnote{Sustainable Web Design - \url{https://sustainablewebdesign.org/}} Grundsätzen entwickelt werden. Dies bedeutet, dass auf effiziente Datenabfragen sowie auf Minderung von Komplexität während
der Entwicklung geachtet wird. Weitere Punkte der Qualitätsanforderungen sind die Möglichkeit nachvollziehbare Logs einzusehen, falls Fehler während
eines Importes entstehen sowie die Wartbarkeit der Anwendung durch modulare und entkoppelte Entwicklung. Außerdem soll die Anwendung mit Unit-Tests abgedeckt sein,
um die Funktionalität des Codes zu gewährleisten.
\subsection{Lastenheft/Fachkonzept}
\label{sec:Lastenheft}
Am Ende der Analysephase wurde mit den Mitarbeitern der \ac{NSD} sowie der \ac{NXP} ein Lastenheft erstellt. Dieses umfasst alle Anforderungen,
welche an die neue Anwendung gestellt werden. Ein Auszug aus dem erstellten Lastenheft befindet sich im \Anhang{app:Lastenheft}.

View file

@ -0,0 +1,9 @@
\section{Authentifizierung}
\label{sec:Authentifizierung}
Die Authentifizierung gegenüber der \acs{API} erfolgt über einen \acs{JWT}-Token, der dem Frontend nach Erfolgreicher Authentifizierung übergeben wird.
Authentifizierung läuft über zwei verschiedene Wege ab:
\begin{itemize}
\item \textbf{Registrierung mit username/password:} Der Nutzer füllt ein Registrierungs-Formular aus, welches die Anmeldedaten an die \acs{API} sendet. Diese validitert die Anmeldedaten und legt bei Erfolg einen neuen Nutzer an. Anschließend wird eine E-Mail-Verifizierungs-Mail gesendet. Bis der Link in der Verifizierungs-Mail nicht angeklickt wurde, ist der Nutzer nicht aktiv und kann sich nicht anmelden. Nach dem Klick auf den Link wird der Nutzer aktiviert und kann sich anmelden.
\item \textbf{Login mit username/password:} Der Nutzer füllt ein Anmelde-Formular, welches die Anmeldedaten an die \acs{API} sendet. Diese prüft die Anmeldedaten und gibt bei Erfolg einen \acs{JWT}-Token zurück. Falls kein Nutzer mit den Anmeldedaten existiert, wird der Nutzer aufgefordert einen Account zu erstellen.
\item \textbf{Login über Oauth (Open Authorization):} Der Nutzer meldet sich mit einem Oauth-Provider an, in unserem Fall Google oder Github. Das Backend leitet den Nutzer zum Oauth-Provider weiter, der die Anmeldedaten prüft und bei Erfolg den Nutzer auf die Applikation weiterleitet und einen Authorization-Code zurück gibt. Mit diesem Code holt sich die \acs{API} einen \acs{JWT} vom jeweiligen Provider und holt sich Nutzer-Informationen. Mit diesen wird dann ein existierender Nutzer eingeloggt, oder registriert falls der Nutzer noch kein Konto hatte. Anschließend wird von der \acs{API} ein \acs{JWT} generiert und an das Frontend weitergegeben.
\end{itemize}

View file

@ -0,0 +1,52 @@
\section{Blackjack}
\subsection{Was ist Blackjack?}
Blackjack ist eines der populärsten Kartenspiele in Casinos weltweit und wurde als vollständiges Spiel in die Casino-Plattform integriert. Das Ziel des Spiels ist es, mit den eigenen Karten einen Wert von 21 zu erreichen oder näher an 21 heranzukommen als der Dealer, ohne dabei über 21 zu gehen (Bust). Das Spiel kombiniert Strategie und Glück, da Spieler Entscheidungen über ihre Spielzüge treffen müssen, während sie gegen einen automatisierten Dealer antreten.
Die Implementierung folgt den klassischen Blackjack-Regeln: Zahlenkarten haben ihren Nennwert, Bildkarten (König, Dame, Bube) zählen 10 Punkte, und Asse können je nach Situation als 1 oder 11 gewertet werden. Ein "Blackjack" (21 mit den ersten beiden Karten) zahlt mit einem Bonus von 1,5x des Einsatzes aus, während reguläre Gewinne den doppelten Einsatz zurückgeben.
\subsubsection{Kartensystem und Deck-Verwaltung}
Das Blackjack-System verwendet ein vollständiges 52-Karten-Deck mit vier Farben (Herz, Karo, Kreuz, Pik) und 13 Rängen (2-10, Bube, Dame, König, Ass). Die Karten werden in der Datenbank als separate Entitäten gespeichert, wobei jede Karte einem Typ zugeordnet ist: DECK (noch im Stapel), PLAYER (Spielerhand) oder DEALER (Dealerhand).
Die DeckService-Klasse verwaltet die Kartenerstellung und -verteilung. Bei Spielbeginn wird ein neues, gemischtes Deck erstellt und die Karten werden entsprechend den Spielregeln verteilt: Der Spieler erhält zwei Karten, der Dealer erhält eine Karte. Die Zufallsmischung erfolgt über java.util.Random, um eine faire Kartenverteilung zu gewährleisten.
\subsubsection{Spielzustände und Ablauf}
Das Spiel durchläuft verschiedene definierte Zustände:
\begin{itemize}
\item \textbf{IN\_PROGRESS:} Das Spiel läuft aktiv, der Spieler kann Aktionen ausführen
\item \textbf{PLAYER\_BLACKJACK:} Der Spieler hat einen natürlichen Blackjack (21 mit zwei Karten)
\item \textbf{PLAYER\_WON:} Der Spieler hat gewonnen ohne Blackjack
\item \textbf{PLAYER\_LOST:} Der Spieler hat verloren oder sich überkauft
\item \textbf{DRAW:} Unentschieden zwischen Spieler und Dealer
\end{itemize}
Der Spielablauf gestaltet sich folgendermaßen:
\begin{enumerate}
\item Spieler startet das Spiel mit einem Einsatz
\item Austeilung der Anfangskarten (2 für Spieler, 1 für Dealer)
\item Spieler trifft Entscheidungen: Hit (weitere Karte), Stand (keine weitere Karte), Double Down (Einsatz verdoppeln und eine Karte)
\item Bei Stand aktiviert sich die Dealer-Logik: Dealer zieht Karten bis mindestens 17 erreicht sind
\item Gewinnermittlung und Auszahlung entsprechend des Ergebnisses
\end{enumerate}
\subsubsection{Handwertberechnung}
Die Berechnung des Handwerts stellt den Kern der Spiellogik dar. Zunächst werden die Grundwerte aller Karten addiert, wobei Asse initial mit 11 bewertet werden. Falls die Summe 21 übersteigt und Asse vorhanden sind, werden diese nacheinander von 11 auf 1 reduziert, bis entweder die Summe unter 22 liegt oder keine Asse mehr als 11 gewertet werden können.
Diese flexible Ass-Bewertung ermöglicht optimale Strategien: Ein Ass kann als "Soft" (11) oder "Hard" (1) gewertet werden, abhängig von den anderen Karten in der Hand. Die Implementierung sorgt automatisch für die bestmögliche Bewertung der Spielerhand.
\subsubsection{Wettsystem und Auszahlungen}
Das Blackjack-Spiel ist vollständig in das Wettsystem der Plattform integriert. Der Einsatz wird zu Spielbeginn vom Spielerkonto abgebucht und bei Gewinn entsprechend der Auszahlungsregeln gutgeschrieben:
\begin{itemize}
\item \textbf{Blackjack:} 1,5x Einsatz plus ursprünglicher Einsatz zurück
\item \textbf{Regulärer Gewinn:} 2x Einsatz (Verdopplung)
\item \textbf{Unentschieden:} Ursprünglicher Einsatz wird zurückerstattet
\item \textbf{Niederlage:} Kein Gewinn, Einsatz verloren
\end{itemize}
Die Double-Down-Funktion verdoppelt den ursprünglichen Einsatz und gibt dem Spieler genau eine weitere Karte, danach ist das Spiel automatisch beendet. Diese Aktion ist nur mit den ersten beiden Karten möglich und erfordert ausreichendes Guthaben für den zusätzlichen Einsatz.
\subsubsection{Frontend-Integration}
Das Frontend bietet eine vollständig animierte Blackjack-Erfahrung mit visueller Kartenrepräsentation und intuitiver Benutzeroberfläche. Die Spielerkarten werden offen dargestellt, während die zweite Dealer-Karte bis zum Spielende verdeckt bleibt. Sound-Effekte und Animationen verstärken die Spielerfahrung.
Die Zustandssynchronisation zwischen Frontend und Backend erfolgt über reactive Programmierung mit Angular Signals, wodurch Änderungen in Echtzeit dargestellt werden. Fehlerbehandlung sorgt für robuste Spielzustände auch bei Netzwerkproblemen, und die Benutzeroberfläche passt sich dynamisch an verschiedene Spielsituationen an.

View file

@ -0,0 +1,53 @@
% !TEX root = ../Projektdokumentation.tex
\section{Continuous Integration}
\label{sec:CI}
Das Projekt verwendet Gitea Actions\footnote{Gitea Actions - \url{https://docs.gitea.com/usage/actions/overview}} als \ac{CI/CD}-Pipeline, welche vollständig kompatibel mit GitHub Actions ist.
Entsprechend den Qualitätsanforderungen soll eine hohe Code-Qualität durch automatisierte Tests gewährleistet werden.
\subsection{Aufbau der CI-Pipeline}
\label{sec:ci-pipeline}
Die Haupt-\ac{CI}-Pipeline wird durch die Datei \Datei{ci.yml} definiert und bei Pull Requests ausgelöst. Aufgrund der separaten Frontend- und Backend-Komponenten
wurde eine \Fachbegriff{Change Detection} implementiert, welche nur relevante Tests für geänderte Bereiche ausführt.
Ein initialer Job identifiziert geänderte Dateien und ermöglicht eine selektive Ausführung:
\begin{itemize}
\item Backend-Änderungen: \Datei{backend/**}
\item Frontend-Änderungen: \Datei{frontend/**}
\item Workflow-Änderungen: \Datei{.gitea/workflows/**}
\end{itemize}
\subsubsection{Backend-Qualitätssicherung}
Für Backend-Änderungen werden folgende Prüfungen durchgeführt:
\begin{itemize}
\item \textbf{Unit Tests:} Ausführung mit \Eingabe{./gradlew test} in OpenJDK 23 Container
\item \textbf{Checkstyle:} Code-Style-Validierung mit Caching-Mechanismus
\item \textbf{Docker Build:} Überprüfung der Build-Funktionalität
\end{itemize}
\subsubsection{Frontend-Qualitätssicherung}
Für Frontend-Änderungen wird eine umfassende Testsuite ausgeführt:
\begin{itemize}
\item \textbf{ESLint:} Code-Qualitätsprüfung mit \Eingabe{bun run lint}
\item \textbf{Prettier:} Code-Formatierungsvalidierung
\item \textbf{Build-Test:} Produktions-Build-Validierung mit \Eingabe{bun run build}
\item \textbf{Playwright \ac{E2E} Tests:} End-to-End-Tests mit automatischem Backend-Start
\item \textbf{Docker Build:} Validierung der Container-Erstellung
\end{itemize}
\subsection{Release-Management}
\label{sec:release-pipeline}
Das Release-Management erfolgt automatisiert durch die \Datei{release.yml} Pipeline bei Pushes auf den \texttt{main}-Branch.
Die Implementierung folgt \Fachbegriff{Semantic Versioning}\footnote{Semantic Versioning - \url{https://semver.org/}} und \Fachbegriff{Conventional Commits}\footnote{Conventional Commits - \url{https://www.conventionalcommits.org/}}.
Die Release-Pipeline umfasst:
\begin{enumerate}
\item \textbf{Semantic Release:} Automatische Versionierung basierend auf Commit-Nachrichten
\item \textbf{Docker Image Build:} Parallele Erstellung von Backend- und Frontend-Images
\item \textbf{Registry Push:} Upload zur privaten Gitea Docker Registry
\end{enumerate}
Die \ac{CI/CD}-Pipeline implementiert Performance-Optimierungen wie intelligentes Caching, Concurrency Control und selektive Job-Ausführung.
Diese Automatisierung gewährleistet eine hohe Software-Qualität bei effizienten Entwicklungsprozessen.

View file

@ -0,0 +1,39 @@
\clearpage
\section{Coinflip}
\subsection{Was ist Coinflip?}
Das Münzwurf-Spiel 'Coinflip' ist ein klassisches Glücksspiel, das in seiner digitalen Umsetzung den traditionellen Münzwurf simuliert. Das Spiel basiert auf dem einfachen Prinzip einer Münze mit zwei Seiten: Kopf und Zahl. Spieler setzen auf eine der beiden Seiten und haben eine 50\%-ige Gewinnchance. Die Einfachheit des Spiels macht es zu einem idealen Einstiegsspiel für neue Nutzer der Casino-Plattform.
Im Gegensatz zu komplexeren Spielen wie Dice bietet Coinflip eine feste Gewinnwahrscheinlichkeit von 50\% und einen konstanten Multiplikator von 2x. Dies bedeutet, dass Spieler bei einem Gewinn ihren Einsatz verdoppeln, während sie bei einer Niederlage ihren gesamten Einsatz verlieren.
\subsubsection{Zufallszahlengenerierung}
Die Implementierung verwendet die Standardklasse java.util.Random zur Generierung des Münzwurfs.
Die Zufallsgenerierung erzeugt einen booleschen Wert, der anschließend einer der beiden Münzseiten zugeordnet wird.
Diese binäre Entscheidung gewährleistet die faire 50:50-Verteilung, die für ein authentisches Münzwurf-Erlebnis erforderlich ist.
\subsubsection{Spielablauf und Datenfluss}
Der Spielablauf von Coinflip folgt einem strukturierten Datenfluss zwischen Frontend und Backend. Der Controller empfängt die Spielanfrage mit folgenden Parametern:
\begin{itemize}
\item \textbf{Einsatz:} Der gesetzte Münzbetrag.
\item \textbf{Gewählte Seite:} Die vom Spieler gewählte Münzseite (Kopf oder Zahl).
\end{itemize}
Nach dem Erhalt der Anfrage führt der Controller eine Guthabenprüfung durch. Bei ausreichendem Guthaben wird die Anfrage an die Service-Schicht weitergeleitet, andernfalls wird eine entsprechende Fehlermeldung zurückgegeben.
Die Service-Klasse verarbeitet die Spiellogik in folgender Reihenfolge:
\begin{enumerate}
\item Abbuchung des Einsatzes vom Spielerkonto.
\item Generierung des zufälligen Münzwurfs (Kopf oder Zahl).
\item Vergleich zwischen gewählter Seite und Wurfergebnis.
\item Bei einem Gewinn: Gutschrift des doppelten Einsatzes auf das Spielerkonto.
\item Rückgabe des Spielergebnisses an das Frontend.
\end{enumerate}
Das Spielergebnis wird strukturiert an das Frontend übermittelt und enthält:
\begin{itemize}
\item Gewinnstatus (gewonnen/verloren)
\item Auszahlungsbetrag (bei Gewinn: 2x Einsatz)
\item Geworfene Münzseite
\end{itemize}

View file

@ -0,0 +1,7 @@
\section{Deployment}
\label{sec:Deployment}
Es gibt zwei Server auf denen Instanzen der Applikation laufen.
\begin{itemize}
\item \textbf{\href{https://casino.simonis.lol/}{Entwicklungsserver}:} Auf dem Entwicklungsserver läuft eine Instanz der Applikation, die für die Entwicklung und das Testen von neuen Features genutzt wird. Diese Instanz ist Lokal bei Constantin gehostet und wird durch einen Cloudflare-Tunnel öffentlich zugänglich gemacht.
\item \textbf{\href{https://trustworthy.casino/}{Produktionsserver}:} Auf dem Produktionsserver läuft die finale Version der Applikation, die für die Nutzer zugänglich ist. Diese Instanz ist öffentlich zugänglich und wird von den Nutzern genutzt. Diese Instanz ist auf einem gemieteten Server gehostet. Die Applikation wird durch eine Nginx Reverse-Proxy bereitgestellt, die Anfragen an die \acs{API} und das Frontend weiterleitet und SSL-Zertifikate verwaltet.
\end{itemize}

View file

@ -0,0 +1,44 @@
\clearpage
\section{Dice}
\subsection{Was ist Dice?}
Das Würfelspiel 'Dice' ist ein originelles Spiel der Casinoplattform Stake.com\footnote{Stake.com ist eine bekannte Online-Glücksspielplattform, die eine Vielzahl von Casinospielen und Sportwetten anbietet.}. Das Spiel dreht sich um einen virtuellen 100-seitigen Würfel,
bei dem Spieler die Parameter ihrer Wette beeinflussen können. Im Kern geht es darum,
einen zuvor festgelegten 'Roll Over'- oder 'Roll Under'-Betrag zu unter- oder überschreiten,
um eine Runde zu gewinnen. Spieler haben die Kontrolle über den Multiplikator und ihre Gewinnchancen:
Durch die Anpassung des Zielwerts können sie das Verhältnis
von Risiko und potenzieller Auszahlung steuern. Ein höherer Multiplikator verspricht zwar größere Gewinne,
reduziert jedoch gleichzeitig die Wahrscheinlichkeit eines erfolgreichen Würfelwurfs.
\subsubsection{Zufallszahlengenerierung}
Zur Generierung des Würfelwurfs verwendet diese Implementierung die Standardklasse java.util.Random.
Sie erzeugt eine pseudo-zufällige Zahl zwischen 1 und 100 (inklusive),
die das Ergebnis des virtuellen 100-seitigen Würfels darstellt.
\subsubsection{Spielablauf und Datenfluss}
Der zentrale Controller steuert den Spielablauf und empfängt die Anfragen vom Frontend. Jede Anfrage enthält die Eckdaten des gewünschten Würfelwurfs:
\begin{itemize}
\item \textbf{Einsatz:} Der gesetzte Münzbetrag.
\item \textbf{Wettart:} Soll der Würfel ``über'' oder ``unter'' einen Wert fallen?
\item \textbf{Zielwert:} Der vom Spieler festgelegte Referenzwert (1-100).
\end{itemize}
Zuerst prüft der Controller das Guthaben des Spielers. Bei unzureichenden Mitteln wird der Vorgang abgelehnt. Andernfalls übergibt er die weitere Ausführung an die Dienstklasse.
Die Dienstklasse übernimmt die eigentliche Logik des Würfelspiels:
\begin{enumerate}
\item Zieht den Einsatz vom Spielerkonto ab.
\item Erzeugt einen zufälligen Würfelwurf (Wert zwischen 1 und 100).
\item Prüft, ob der Wurf die Gewinnbedingung erfüllt (entsprechend Wettart und Zielwert).
\item Berechnet die Gewinnwahrscheinlichkeit und den sich daraus ergebenden Multiplikator.
\item Schreibt bei einem Gewinn den entsprechenden Betrag (Einsatz $\times$ Multiplikator) dem Spielerkonto gut.
\end{enumerate}
Das Ergebnis des Spiels wird an das Frontend zurückgesendet und enthält:
\begin{itemize}
\item Gewinnstatus (gewonnen/verloren)
\item Auszahlungsbetrag
\item Gewürfelten Wert
\end{itemize}

View file

@ -0,0 +1,7 @@
% !TEX root = ../Projektdokumentation.tex
\section{Dokumentation}
\label{sec:Dokumentation}
Die Dokumentation der Anwendung besteht aus zwei Bestandteilen: der Projektdokumentation, in welcher der Autor die einzelnen
Phasen, die während der Projektumsetzung durchlaufen wurden, beschreibt sowie der Entwicklerdokumentation, bei der es sich um eine
detaillierte Beschreibung der Klassen, die von der Anwendung genutzt werden, handelt. Außerdem werden auch deren Attribute und Methoden sowie die
Abhängigkeiten der jeweiligen Klassen untereinander erläutert.

View file

@ -0,0 +1,12 @@
% !TEX root = ../Projektdokumentation.tex
\section{Einführungsphase}
\label{sec:Einfuehrungsphase}
Durch die in Abschnitt~\ref{sec:ImplementierungGeschaeftslogik}: \nameref{sec:ImplementierungGeschaeftslogik} vorgenommene Implementierung
der Anwendung als Composer basierte Packages, ist das zur Verfügung stellen der Anwendung an den \ac{NSD} internen Satis \footnote{Composer Satis - \url{https://github.com/composer/satis}} Server angebunden.
Der interne Satis dient als Composer Repository und stellt so eigen entwickelte Module für die \ac{NSD} für alle Kundenprojekte zur Verfügung.
Die Komponenten der Anwendung werden dort aufgeführt und können in die realen Kundenprojekte nach Fertigstellung der ausgelassenen
Funktionen per Composer implementiert werden. Hier kommt nun auch der größte Vorteil zu tragen, da eine Änderung der Module lediglich
in der Grundversion, die dem Satis zur Verfügung steht, vorgenommen muss und somit automatisch per Composer bei Deployments für Live Umgebungen übernommen werden.
So müssen Änderungen nicht code-seitig an den Projekten vorgenommen werden.

View file

@ -0,0 +1,55 @@
% !TEX root = ../Projektdokumentation.tex
\section{Einleitung}
\label{sec:Einleitung}
Die folgende Projektdokumentation behandelt den Ablauf des IHK-Abschlussprojekts, welches der Autor im Rahmen seiner Ausbildung
zum Fachinformatiker mit der Fachrichtung Anwendungsentwicklung durchgeführt hat. Ausbildungsbetrieb ist die \ac{NSD},
ein Tochterunternehmen der team neusta Unternehmensgruppe mit Sitz in Bremen. Das Kerngeschäft der \ac{NSD} umfasst die Beratung,
Entwicklung und Umsetzung von komplexen Software- und \ac{eCommerce}-Lösungen und beschäftigt zur Zeit ca. 1000 Mitarbeiter.
\subsection{Projektumfeld}
\label{sec:Projektumfeld}
Auftraggeber des Projektes ist die \ac{NXP}, ebenfalls eine Tochtergesellschaft der team neusta Unternehmensgruppe.
Zu den Leistungen der \ac{NXP} gehören die Beratung und Umsetzung der Bereiche Konzeption, Design und Usability sowie die Leitung von Web- und \ac{eCommerce}-Projekten.
Die technische Umsetzung von Web- und \ac{eCommerce}-Projekten für Kunden der \ac{NXP} wird in Zusammenarbeit mit Mitarbeitern der \ac{NSD} vorgenommen.
Diese Form der Zusammenarbeit erfordert intensive, regelmäßige Kommunikation und Rücksprache zwischen beiden Parteien.
\subsection{Projektziel}
\label{sec:Projektziel}
Ziel des Projektes ist die Entwicklung einer Schnittstelle zum Importieren und Exportieren von Produkt- und Nutzerdaten
zwischen dem \ac{CRM} \ac{IX} und einem \ac{M2} Webshop.
Die \ac{NSD} entwickelt für Kunden der \ac{NXP} spezifische Webshops und bindet diese an das vom Kunden vorgesehene \ac{CRM} an.
Für \ac{IX} erfordert dies eine individuelle Entwicklung pro Kunden, welche mit hohem Aufwand und Kosten verbunden ist.
Dieses Projekt soll einen modularen Rahmen für Importe/Exporte zwischen \ac{M2}, einer Open-Source \ac{eCommerce} Platform
auf \ac{PHP} Basis und \ac{IX} abbilden, welcher in verschiedene Kundenprojekte implementiert werden kann und so die
abermalige Neuentwicklung eines Import/Export Modules ablöst.
\subsection{Projektbegründung}
\label{sec:Projektbegruendung}
Die \ac{NSD} entwickelt derzeit für jeden Kunden, der \ac{IX} als \ac{CRM} nutzt, individuell ein Modul zur Erweiterung
des relevanten \ac{M2}.
Diese Module handhaben den Kunden- sowie Produktdaten-Import von \ac{IX} zu \ac{M2}. Die Neuentwicklungen für jeden
Kunden beinhalten Schwierigkeiten in der Wartung und Fehleranalyse, da jeder Entwickler sich in das individuell entwickelte Modul
einarbeiten muss. Gleichzeitig liegt hier kein Standard vor, wie mit Fehlermeldungen, die von der \ac{IX}-\acs{API} empfangen werden, umgegangen wird.
Dies resultiert in längerer und umständlicher Wartung und schlägt dem Kunden durch Mehraufwand zu Buche, der vermieden werden kann.
Ein modularer Rahmen mit einfachen Individualisierungsmöglichkeiten für einen \ac{IX}-Importer als Modul für \ac{M2} sorgt somit für
eine Minderung von Neu-Entwicklungskosten und -aufwand. Eine höhere Wartbarkeit mit geringerer Einarbeitungszeit pro Kundenprojekt wird hierdurch
ebenfalls garantiert.
\subsection{Projektschnittstellen}
\label{sec:Projektschnittstellen}
Damit die Daten, die zu \ac{M2} importiert werden sollen, vollständig ermittelt und validiert werden können, muss die Anwendung mit
der \ac{IX}-\acs{API} interagieren können. Diese Anforderung soll mit Hilfe von cURL \footnote{cURL - Client URL \url{https://github.com/curl/curl}} im Umfeld der \ac{PHP} Entwicklung umgesetzt werden.
Um den eigentlichen Import-Vorgang der bereits geholten Daten von \ac{IX} starten zu können wird zudem eine Verbindung zur Import-\acs{API} von \ac{M2} benötigt.
Aus diesem Grund wird die Anwendung als \ac{M2}-Modul implementiert. So wird garantiert, dass Fehler im Import-Vorgang minimiert werden, weil der Fokus darauf gelegt
wird, die \ac{M2} eigenen Import-Funktionen zu nutzen.
\subsection{Projektabgrenzung}
\label{sec:Projektabgrenzung}
Da der Projektumfang beschränkt ist, soll die Entwickung der Import- und Export-Funktionen von Bestellungen und Warenkörben nicht Bestandteil dieses Abschlussprojektes sein.

View file

@ -0,0 +1,73 @@
% !TEX root = ../Projektdokumentation.tex
\section{Entwurfsphase}
\label{sec:Entwurfsphase}
\subsection{Zielplattform}
\label{sec:Zielplattform}
Das Abschlussprojekt soll, wie in Abschnitt~\ref{sec:Projektziel}: \nameref{sec:Projektziel} beschrieben, aufgrund des Aspektes der Fehlerminimierung als \ac{M2}-Modul
umgesetzt werden. Zur temporären Zwischenspeicherung der importierten Datensätze von \ac{IX} wird eine Tabelle in das
bestehende Datenbank-System der \ac{M2} Instanz implementiert.
Die Auswahl der Programmiersprache, mit der das Projekt realisiert werden soll, wurde anhand der Anforderungen von \ac{M2}
als \ac{eCommerce} Platform durchgeführt. Um eine Fehler minimierende Einbindung in bestehende Shops zu garantieren, wurde beschlossen,
auf eine Nutzwertanalyse zu verzichten und den genannten Anforderungen von \ac{M2} Folge zu leisten.
Daher ist die Programmiersprache \ac{PHP}, unter Berücksichtigung der genannten Gesichtspunkte, am besten geeignet und soll für die Umsetzung des Projektes verwendet werden.
\subsection{Architekturdesign}
\label{sec:Architekturdesign}
Die Implementierung der einzelnen Import-Funktionen für Benutzer- und Produktdaten sollen auf Basis des Factory Design Pattern \footnote{PHP the Right Way - Factory Pattern - \url{https://phptherightway.com/pages/Design-Patterns.html}}
umgesetzt werden. Demnach wird jede Import-Komponente durch eine zugehörige Factory per Singleton Prinzip instanziiert.
So wird sichergestellt, dass jeweils nur eine Instanz des Imports vorhanden ist und Rechenlast während der Nutzung der Anwendung
minimiert wird.
Zusätzlich wird jede Funktionalität modular als Composer \footnote{Composer - \url{https://getcomposer.org}} Package eingebunden, sodass die einzelnen Komponenten nur eine Basis-Komponente zum
Funktionieren benötigen. Die Basis-Komponente bindet alle gewünschten Komponenten ein und kann sie anhand des o.g. Factory Patterns instanziieren.
Diese Modularität bildet eine übersichtliche Anwendungsgestaltung, die nachträglich - ohne viel Aufwand - um mehr Funktionalität erweitert werden kann.
\subsection{Entwurf der Benutzeroberfläche}
\label{sec:Benutzeroberflaeche}
Der Autor hat sich auf Grund des festgelegten Projektumfangs sowie des festgelegten Nutzerkreises, der aus Mitarbeitern der \ac{NSD} besteht,
für eine Umsetzung der Benutzeroberfläche als \ac{CLI}, zur Ausführung der in
Abschnitt~\ref{sec:Anwendungsfaelle}: \nameref{sec:Anwendungsfaelle} beschriebenen Anwendungsfälle, entschieden.
Die Einbindung der Konsolenbefehle soll über die standardisierte \ac{M2} Implementierungsmöglichkeit für \ac{CLI} Befehle erfolgen.
\subsection{Datenmodell}
\label{sec:Datenmodell}
Um eine Zwischenspeicherung der Daten, die von der \ac{IX}-\ac{API} bereitgestellt werden, zu realisieren, wird eine Tabelle zur
Datenstruktur vom betroffenen \ac{M2} Webshop hinzugefügt. Diese Tabelle soll lediglich Informationen über die importierten Daten und den
jeweiligen Zeitstempel zur Nachvollziehbarkeit enthalten.
Da keine komplexen Entitäten hierfür benötigt werden, wurde vom Autor darauf verzichtet ein \ac{ERM} sowie eine Datenbankstruktur zu
erstellen.
\subsection{Geschäftslogik}
\label{sec:Geschaeftslogik}
Wie in Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschrieben, wird die Anwendung in mehrere Komponenten aufgeteilt.
Die Aufteilung der Komponenten erfolgt per Registrierung als Composer Package. Composer als \ac{PHP} Package Manager bietet die Möglichkeit,
Abhängigkeiten der genutzten Software zu versionieren und in einem kontrollierten Umfeld zu nutzen. Durch die Aufteilung der Anwendung in solche
Packages, erlangt der Autor eine entkoppelte Anwendung, die ohne großen Aufwand ebenfalls erweitert werden kann.
Es wird eine Basis-Komponente geben von der jede Subkompenente ableitet. Diese Basis-Komponente beinhaltet die Grundabhängigkeiten,
damit die Anwendung im jeweiligen \ac{M2} Umfeld lauffähig ist. Diese Grundabhängigkeiten beinhalten die Version der Programmiersprache
\ac{PHP}, die Version des genutzten \ac{M2} sowie die genauen Abhängigkeiten der genutzten \ac{M2} Kern-Komponenten. Zusätzlich wird eine Version
der Anwendung selbst definiert, sodass in der weiteren Entwicklung eigene Versionen für verschiedene \ac{M2} Versionen (\zB ältere) zur Verfügung gestellt
werden könnten. Die Basis Komponente wird den Namen neusta-m2-intex-base tragen.
neusta-m2-intex-base wird erweitert um folgende Subkomponenten:
\begin{itemize}
\item neusta-m2-intex-client: Subkomponente zur Verbindung zur \ac{IX} \ac{API}
\item neusta-m2-intex-client-config: Subkomponente zur Konfiguration des Key-Value Mappings für Daten von \ac{IX}
\item neusta-m2-intex-cli: Subkomponente zur Implementierung der Benutzeroberfläche
\item neusta-m2-intex-customer: Subkomponente zur Implementierung der Import Logik für Nutzerdaten
\item neusta-m2-intex-catalog: Subkomponente zur Implementierung der Import Logik für Produktdaten
\end{itemize}
Durch die Namenskonvention, die vom Autor gewählt wurde, ist für aussenstehende Entwickler schneller ersichtig, in welcher Komponente
welche Logik eingebaut wurde. So wird weiterhin die Wartungsfähigkeit der Anwendung in den Vordergrund gestellt.

View file

@ -0,0 +1,38 @@
% !TEX root = ../Projektdokumentation.tex
\section{Fazit}
\label{sec:Fazit}
\subsection{Soll-/Ist-Vergleich}
\label{sec:SollIstVergleich}
Bei der rückblickenden Betrachtung des Projektes, wird vom Autor festgehalten, dass die zuvor festgelegten Anforderungen erfüllt wurden.
Die Entwicklung des Projektes hat einen Grundstein für ein modulares Import/Export System von \ac{M2} zu \ac{IX} gelegt, welches allerdings zur vollständigen
Ersetzung der alten Module noch erweitert werden muss. Der Autor hat dies allerdings berücksichtigt und gemäß Abschnitt~\ref{sec:Projektabgrenzung}: \nameref{sec:Projektabgrenzung}
aufgrund des begrenzten Projektumfangs eingeplant.
Wie der Tabelle~\ref{tab:Vergleich} zu entnehmen ist, konnte ebenfalls die Zeitplanung bis auf wenige Ausnahmen eingehalten werden.
\tabelle{Soll-/Ist-Vergleich}{tab:Vergleich}{Zeitnachher.tex}
\subsection{Lessons Learned}
\label{sec:LessonsLearned}
Der Autor konnte während des Projektes wertvolle Erfahrungen \bzgl der Planung und Durchführung von Software-Projekten
sammeln. Hierbei wurde besonders deutlich, welch große Bedeutung stetige Rücksprache und Kommunikation mit den Projektbeteiligten
für den Projekterfolg hat. Zusätzlich konnte der Autor neue Kompetenzen und Sicherheiten im Umgang mit \ac{M2} erlangen, welche
für die zukünftige, angestrebte Tätigkeit im \ac{eCommerce} hilfreich sind.
Abschließend lässt sich sagen, dass die Realisierung des Projektes eine Erleichterung zur alltäglichen Arbeit mit \ac{M2}
Webshops, die eine \ac{IX} Schnittstelle nutzen, darstellt und auch für den Autor während der Entwicklung eine Bereicherung war.
\subsection{Ausblick}
\label{sec:Ausblick}
Die im Lastenheft definierten Anforderungen wurden zwar realisiert, dennoch können in Zukunft noch weitere Anforderungen \bzw
Erweiterungsmöglichkeiten entwickelt werden. Es kann \zB die Erweiterung der Benutzeroberfläche in das bestehende \ac{M2} Administrator
Backend als \ac{GUI} vorgenommen werden. Gleichzeitig können die Funktionen um weitere Datentypen erweitert werden, wie \zB
Mediadaten und Bestellungen. Eine Möglichkeit zum Export von allen importierten Daten zu \ac{IX} selbst, sind ebenfalls Aussichten für die Zukunft.
Aufgrund des im Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschriebenen modularen Aufbaus, können die Anpassungen
\bzw Erweiterungen einfach vorgenommen werden. Die Modularität der Anwendung ermöglicht somit eine gute Wart- und Erweiterbarkeit.

View file

@ -0,0 +1,82 @@
% !TEX root = ../Projektdokumentation.tex
\section{Implementierungsphase}
\label{sec:Implementierungsphase}
\subsection{Implementierung der Datenstrukturen}
\label{sec:ImplementierungDatenstrukturen}
Wie in Abschnitt~\ref{sec:Datenmodell}: \nameref{sec:Datenmodell} beschrieben, ermöglicht \ac{M2} eine Einbindung von individuell benötigten \acs{SQL}
Tabellen in die vorhandene Datenstruktur.
Dem \Anhang{app:InstallData} kann ein \acs{XML} entnommen werden, welches der Komponente neusta-m2-intex-base hinzugefügt wurde.
Dieses deklarative Initialisieren von Datenstrukturen wird ebenfalls vom Framework Symfony genutzt. Es ermöglicht dem Entwickler anzugeben,
wie die Datenstruktur einer Tabelle aussehen soll. \ac{M2} bestimmt dann den Unterschied der derzeitigen Tabellenstruktur und der Struktur, die durch
vorhandene \acs{XML} Definitionen angegeben wurde. Diese Unterschiede werden dann durch atomare \acs{SQL} Operationen wiedergespiegelt.
Zusätzlich priorisiert \ac{M2} deklarative Schemen und führt diese generell vor allen älteren Schema \ac{PHP} Scripten aus.
Die bestehende Datenbank wurde durch o.g. vorgehen um eine Basis-Tabelle erweitert, welche zur Nachvollziehbarkeit der Import-Vorgänge beitragen soll.
\subsection{Implementierung der Benutzeroberfläche}
\label{sec:ImplementierungBenutzeroberflaeche}
Die Implementierung der Benutzeroberfläche erfolgte, wie bereits im Abschnitt~\ref{sec:Benutzeroberflaeche}: \nameref{sec:Benutzeroberflaeche} geplant,
mit Hilfe der \ac{M2} eigenen Möglichkeiten zur Einbindung von \ac{CLI}-Befehlen.
Durch die Entscheidung des Autors, die Anwendung als \ac{M2} Modul umzusetzen, ergibt sich hier der Vorteil, dass die gewünschten und benötigten
\ac{CLI} Befehle per Dependency Injection direkt in die \ac{M2} Befehlsliste aufgenommen werden können. Somit können Entwickler bei der Nutzung der Anwendung
auf das Standard Interface von \ac{M2} zurückgreifen und separate Zugangsdaten oder Aufrufe werden vermieden.
Um der \ac{M2} Instanz die gewünschten Befehle zuzufügen, wurde die Klasse CliCommand der Komponente neusta-m2-intex-cli hinzugefügt. Diese Klasse
leitet von der abstrakten \ac{M2} Klasse Command ab und bindet in \ac{M2} inkludierte Symfony-Komponenten zur Verarbeitung von Ein- und Ausgabe ein.
\subsection{Implementierung der Geschäftslogik}
\label{sec:ImplementierungGeschaeftslogik}
Da die Implementierung der Geschäftslogik den Kernbestandteil des gesamten Projektes darstellt, soll diese im folgenden Abschnitt
genauer erläutert werden. Um die Implementierung möglichst komfortabel durchzuführen, wurde die Entwicklungsumgebung JetBrains PHPStorm 2019 hierfür
vom Autor gewählt.
Zu Beginn der Implementierung wurde das Grundgerüst der Komponenten für die Anwendung erstellt. Hierzu wurde für jede in
Abschnitt~\ref{sec:Geschaeftslogik}: \nameref{sec:Geschaeftslogik} erwähnte Komponente und Subkomponente die Grundlage zur Einbindung als
Composer Package gelegt. Jede Komponente beinhaltet eine \acs{JSON} Datei, die Angaben zum Namen des Packages, der Version, einer Package-Typ Definition
(hier: magento2-module), Abhängigkeiten zu anderen Packages sowie Informationen zum Autor beinhaltet (Beispiel: \Anhang{app:ComposerJson}). Somit konnten die Komponenten
im einzelnen als separates Projekt angesehen werden.
Nachdem die Grundlagen zur Aufteilung der Anwendung in modulare Komponenten gelegt wurde, befasste sich der Autor damit, die lokale Entwicklungsumgebung aufzusetzen.
Hierzu wurde ein für \ac{M2} bereits vorhandenes Docker \footnote{Docker - \url{https://www.docker.com}} Setup der \ac{NSD} genutzt. Docker ist ein \ac{VM} Container System, welches im genutzten Setup Container für
jeweils den Quellcode der \ac{M2} Instanz, der Datenbank sowie dem benötigten NGINX \footnote{NGINX - \url{https://www.nginx.com/}} Server bereit stellt. Dem Autor wurde hiermit ein natives Aufsetzen einer \ac{M2} Instanz
erspart, was zur Qualität der Entwicklung erheblich beitrug und gleichzeitig garantiert, dass die Anwendung auf der tatsächlichen Serverumgebung lauffähig ist.
Nach der Fertigstellung des Grundgerüstes und der lokalen Umgebung konnte mit der eigentlichen Implementierung fortgesetzt werden.
Wie in Abschnitt~\ref{sec:Entwicklungsprozess}: \nameref{sec:Entwicklungsprozess} beschrieben, entschied der Autor sich für eine agile Umsetzung in einer Mischung
aus Kanban und Scrum. Jede einzelne Komponente ergab somit eine Story im Kanban Board, welche nach Scrum Prinzip zusammen mit den Mitarbeitern der \ac{NSD} priorisiert wurden.
Die Implementierung des Basis Moduls neusta-m2-intex-base wurde zügig Vollzogen, da die Komponente lediglich als Wrapper für alle Funktionen dienen soll.
Die o.g. Priorisierung gemäß Scrum sah nun vor, dass die Implementierung der Verbindungslogik zu \ac{IX} am wichtigsten ist, da alle weiteren Logik-Komponenten hierrauf aufbauen müssen.
Deswegen soll an dieser Stelle die Implementierung der Komponente neusta-m2-intex-client als Beispiel herangezogen werden.
Zunächst wurde in der \acs{JSON} Datei für Composer definiert, dass neusta-m2-intex-base die Grundabhängigkeit für das Modul darstellt. So wurden duplizierte
Einträge in der Konfiguration vermieden, da diese bereits in der Komponente neusta-m2-intex-base inkludiert sind. Zusätzlich besteht eine Abhängigkeit zur Komponente
neusta-m2-intex-client-config, da in der Komponente die Konfigurationen für die \ac{IX}-\acs{API} Zugriffe vorgenommen werden sollen. Die Konfigurationen beinhalten neben
den Key-Value Paaren zum Mapping der Produkt- und Nutzerattribute auf den \ac{M2} Standard auch die grundlegenden Informationen wie Passwort und Nutzername zur Verbindung
mit \ac{IX}.
Die Aufgabe des neusta-m2-intex-client in der Anwendung soll sein, jegliche Datenverbindung von der entwickelnden Anwendung mit der \ac{IX}-\acs{API}
herzustellen und gleichzeitig ein nachvollziehbares Logging dieser Verbindungen und eventuell auftretender Fehler zur Verfügung zu stellen.
Wie in Abschnitt~\ref{sec:Architekturdesign}: \nameref{sec:Architekturdesign} beschrieben, sah der Entwurf vor, das Factory Design Pattern zu nutzen und so
mehrere Instanzen der Verbindungen zu vermeiden. Hierzu wurde in der Komponente neusta-m2-intex-client die Klasse Factory implementiert, welche die Instanziierung
der Klassen abbildete, die neusta-m2-intex-client der Anwendung zur Verfügung stellen soll. Der Grundgedanke ist hierbei, dass die Komponente zum Import der Nutzerdaten
(hier: neusta-m2-intex-customer) die Factory des neusta-m2-intex-client nutzen und so seine Verbindung zu \ac{IX} herstellen lassen kann. Der Quellcode der Factory kann
dem \Anhang{app:Factory} entnommen werden.
Um Requests zur \ac{IX}-\acs{API} zu verarbeiten, entschied der Autor, den Open Source \ac{HTTP} Client GuzzlePhp \footnote{GuzzlePhp - \url{https://github.com/guzzle/guzzle}} zu nutzen. Hierdurch erlangte der Autor die Möglichkeit,
asynchrone Requests an die \acs{API} von \ac{IX} zu stellen, ohne einen eigenen \ac{PHP} \acs{HTTP} Client entwickeln zu müssen.
Die Factory instanziiert nun die beim Aufruf angeforderte Klasse. Hier als Beispiel CustomerConnection (siehe \Anhang{app:CustomerConnection} und \Anhang{app:Connection}), welche im
CustomerDataController in der Komponente neusta-m2-intex-customer instanziiert wird (siehe \Anhang{app:CustomerDataController}).
Durch den Fokus auf das Fertigstellen der neusta-m2-intex-client Komponente, waren alle folgenden Subkomponenten trivialer zu implementieren, da bei einem Datenimport
die Abfrage der Daten der Hauptbestandteil einer solchen Anwendung darstellt. Dem folgend wurde vom Autor in Reihenfolge die Logik zur Verarbeitung der erhaltenen Daten
implementiert (neusta-m2-intex-customer \& neusta-m2-intex-catalog) sowie die Möglichkeit die Funktionalität über einen \acs{CRON}-Job anstoßen zu können, welche
im \ac{M2} Standard per \acs{XML} Datei inkludiert werden kann.

View file

@ -0,0 +1,78 @@
\section{Lootboxes}
\subsection{Was sind Lootboxes?}
Lootboxes sind digitale Belohnungsbehälter, die gegen eine feste Gebühr geöffnet werden können und dem Spieler einen zufälligen Gewinn basierend auf vordefinierten Wahrscheinlichkeiten gewähren. Das System orientiert sich an bekannten Gaming-Mechaniken und bietet Spielern die Möglichkeit, durch Glück höhere Gewinne zu erzielen als den bezahlten Einsatz. Jede Lootbox enthält verschiedene Belohnungen mit unterschiedlichen Gewinnwahrscheinlichkeiten, wodurch ein Spannungselement entsteht.
Das Lootbox-System der Casino-Plattform umfasst sowohl die Verwaltung verschiedener Lootbox-Typen als auch ein animiertes Öffnungserlebnis, das an populäre Spiele wie Counter-Strike erinnert. Spieler können zwischen verschiedenen Lootboxes wählen, die sich in Preis und Belohnungsstruktur unterscheiden.
\subsubsection{Wahrscheinlichkeitssystem und Belohnungsverteilung}
Das Herzstück des Lootbox-Systems ist der Wahrscheinlichkeitsalgorithmus, der faire und nachvollziehbare Belohnungsverteilungen gewährleistet. Jede Belohnung in einer Lootbox hat eine definierte Wahrscheinlichkeit zwischen 0,0 und 1,0 (0\% bis 100\%). Die Gewinnermittlung erfolgt durch einen kumulativen Wahrscheinlichkeitsansatz:
\begin{enumerate}
\item Generierung einer Zufallszahl zwischen 0 und 1
\item Iteration durch alle Belohnungen mit Akkumulation der Wahrscheinlichkeiten
\item Rückgabe der ersten Belohnung, bei der die Zufallszahl kleiner oder gleich der kumulativen Wahrscheinlichkeit ist
\item Fallback zur letzten Belohnung bei keiner Übereinstimmung (Sicherheitsmechanismus)
\end{enumerate}
Dieses System ermöglicht eine präzise Kontrolle über die Verteilung der Belohnungen und gewährleistet, dass seltene Gegenstände entsprechend ihrer konfigurierten Wahrscheinlichkeit auftreten.
\subsubsection{Seltenheitssystem}
Die Lootboxes verwenden ein sechsstufiges Seltenheitssystem, das visuell durch Farbkodierung dargestellt wird:
\begin{itemize}
\item \textbf{Common (Häufig):} 40\%+ Wahrscheinlichkeit - Blau
\item \textbf{Uncommon (Ungewöhnlich):} 20-40\% Wahrscheinlichkeit - Grün
\item \textbf{Rare (Selten):} 10-20\% Wahrscheinlichkeit - Blau
\item \textbf{Epic (Episch):} 5-10\% Wahrscheinlichkeit - Lila
\item \textbf{Legendary (Legendär):} 1-5\% Wahrscheinlichkeit - Gold
\item \textbf{Mythic (Mythisch):} <1\% Wahrscheinlichkeit - Rot
\end{itemize}
Die Farbkodierung wird sowohl in der Auswahlansicht als auch während der Öffnungsanimation verwendet, um Spielern sofort die Seltenheit ihrer Belohnung zu kommunizieren.
\subsubsection{Animiertes Öffnungserlebnis}
Das Frontend bietet ein hochgradig animiertes Öffnungserlebnis, das die Spannung und das Engagement der Spieler steigert. Die Öffnungssequenz umfasst:
\begin{enumerate}
\item \textbf{Auswahlphase:} Rasteranzeige verfügbarer Lootboxes mit Preis und möglichen Belohnungen
\item \textbf{Öffnungsanimation:} 10-sekündige horizontale Scrollanimation mit 120 Gegenständen
\item \textbf{Gewinnermittlung:} Hervorhebung des Gewinnergegenstands an Position 60
\item \textbf{Ergebnisdarstellung:} Einblendanimation für Gewinn und Gewinn-/Verlustberechnung
\end{enumerate}
Die Animation generiert eine Walze mit 120 Gegenständen, wobei der tatsächliche Gewinn immer an der mittleren Position (60) platziert wird. Dies erzeugt den Eindruck einer echten Zufallsauswahl, obwohl das Ergebnis bereits vorher feststeht.
\subsubsection{Datenmodell und Verwaltung}
Das Backend verwendet ein flexibles Datenmodell, das die Erstellung und Verwaltung verschiedener Lootbox-Typen ermöglicht:
\textbf{LootBoxEntity:} Repräsentiert eine Lootbox mit Namen, Preis und zugehörigen Belohnungen. Die Beziehung zu Belohnungen erfolgt über eine Viele-zu-Viele-Verknüpfung, wodurch Belohnungen zwischen verschiedenen Lootboxes geteilt werden können.
\textbf{RewardEntity:} Definiert einzelne Belohnungen mit Wert und Wahrscheinlichkeit. Die Wahrscheinlichkeit wird als Dezimalzahl mit einer Genauigkeit von 5 Stellen und 2 Nachkommastellen gespeichert.
Die Verwaltung erfolgt über REST-Endpunkte, die sowohl das Abrufen verfügbarer Lootboxes als auch das Kaufen und Öffnen ermöglichen. Administrative Funktionen erlauben das Erstellen neuer Lootboxes und das Löschen bestehender.
\subsubsection{Kaufprozess und Guthaben-Integration}
Der Lootbox-Kaufprozess ist nahtlos in das Guthaben-Management-System der Plattform integriert:
\begin{enumerate}
\item Validierung des Benutzerguthabens gegen den Lootbox-Preis
\item Sofortige lokale Guthabenabzug für responsives Benutzererlebnis
\item Backend-API-Aufruf zur Kaufabwicklung
\item Server-seitige Belohnungsermittlung mittels Wahrscheinlichkeitsalgorithmus
\item Guthaben-Update (Preis abziehen, Belohnung hinzufügen)
\item Frontend-Synchronisation und Animationsstart
\end{enumerate}
Das System gewährleistet durch transaktionale Datenbankoperationen, dass Guthaben-Updates atomisch erfolgen und keine inkonsistenten Zustände entstehen können.
\subsubsection{Sicherheit und Fairness}
Die Lootbox-Implementierung legt besonderen Wert auf Sicherheit und Fairness:
\textbf{Server-seitige Autorität:} Alle Belohnungsermittlungen erfolgen ausschließlich auf dem Server, wodurch Client-seitige Manipulationen ausgeschlossen werden.
\textbf{Eingabevalidierung:} Sowohl die Datenübertragungsobjekte als auch die Backend-Services validieren alle Eingaben auf Korrektheit und Bereichsgrenzen.
\textbf{Wahrscheinlichkeitsintegrität:} Das System überwacht die Wahrscheinlichkeitswerte und gewährleistet, dass sie im gültigen Bereich (0,0-1,0) liegen.
Die Implementierung bietet somit ein vollständiges, produktionsreifes Lootbox-System mit robusten Frontend-Animationen, ordnungsgemäßer Backend-Validierung und nahtloser Benutzerintegration.

View file

@ -0,0 +1,40 @@
% !TEX root = ../Projektdokumentation.tex
\section{Projektarchitektur}
\label{sec:Projektarchitektur}
\subsection{Überblick}
Das Casino Gaming Platform Projekt folgt einer klassischen Client-Server-Architektur mit einer klaren Trennung zwischen Frontend und Backend. Diese Architektur wurde gewählt, um eine saubere Separation of Concerns zu gewährleisten und die Wartbarkeit sowie Erweiterbarkeit des Systems zu fördern. Die Kommunikation zwischen den beiden Schichten erfolgt über REST-\acs{API}s, die \acs{JSON}-Daten austauschen.
\subsection{Technologie-Stack}
\subsubsection{Frontend-Technologien}
Für die Entwicklung der Benutzeroberfläche wurde Angular\footnote{Angular - \url{https://angular.io/}} als Framework gewählt. Angular bietet eine robuste Basis für Single Page Applications und ermöglicht eine komponentenbasierte Entwicklung. Als Package Manager kommt Bun\footnote{Bun - \url{https://bun.sh/}} zum Einsatz, welcher sowohl die Paketinstallation als auch das Bundling übernimmt. Für das Styling wird Tailwind CSS\footnote{Tailwind CSS - \url{https://tailwindcss.com/}} verwendet, welches eine konsistente und effiziente Gestaltung der Benutzeroberfläche ermöglicht.
Für die Qualitätssicherung werden \acs{E2E}-Tests mit Playwright\footnote{Playwright - \url{https://playwright.dev/}} durchgeführt. Diese Tests stellen sicher, dass die gesamte Anwendung aus Benutzersicht korrekt funktioniert.
\subsubsection{Backend-Technologien}
Das Backend basiert auf Spring Boot, einem Java-Framework, das eine schnelle Entwicklung von produktionsreifen Anwendungen ermöglicht. Spring Boot wurde gewählt, da es umfangreiche Funktionalitäten out-of-the-box bietet und sich durch eine starke Community-Unterstützung auszeichnet. Als Build-Tool kommt Gradle zum Einsatz, welches flexiblere Konfigurationsmöglichkeiten als Maven bietet.
Für die Datenpersistierung wird PostgreSQL\footnote{PostgreSQL - \url{https://www.postgresql.org/}} verwendet.
\subsection{Systemarchitektur}
\subsubsection{Frontend-Architektur}
Das Frontend wurde als Single Page Application (SPA) konzipiert, um eine flüssige Benutzererfahrung zu gewährleisten. Die Architektur folgt Angulars modularem Ansatz und gliedert sich in verschiedene Bereiche: Feature-Module organisieren die Funktionalitäten nach Geschäftsbereichen wie Spiele und Einzahlungen. Wiederverwendbare UI-Komponenten wurden in einem Shared-Bereich zusammengefasst, um Code-Duplikation zu vermeiden.
Services übernehmen die Kommunikation mit dem Backend und kapseln die Geschäftslogik. \acs{HTTP}-Interceptors behandeln globale Aspekte wie Fehlerbehandlung zentral.
\subsubsection{Backend-Architektur}
Das Backend implementiert eine klassische mehrschichtige Architektur, die eine klare Trennung der Verantwortlichkeiten gewährleistet. Die Controller-Schicht stellt die REST-\acs{API}-Endpunkte bereit und behandelt \acs{HTTP}-Anfragen. Die Service-Schicht enthält die Geschäftslogik und orchestriert verschiedene Use Cases.
Die Repository-Schicht abstrahiert den Datenzugriff und verwendet Spring Data JPA für die Kommunikation mit der Datenbank. Entity-Klassen repräsentieren die Domain-Modelle und bilden die Datenbankstrukturen ab.
\subsection{Datenarchitektur}
Die Datenbank folgt einem relationalen Design mit klar definierten Entitätsbeziehungen. Das Schema gliedert sich in mehrere Hauptbereiche: Der User Management Bereich verwaltet Benutzerkonten und Benutzerprofile. Spielbezogene Daten wie Spielstände, Wetten und Ergebnisse werden in separaten Tabellen gespeichert, um die Integrität der Spiellogik zu gewährleisten.
Der Financial Bereich behandelt alle monetären Transaktionen, Guthaben und Einzahlungen mit entsprechenden Audit-Trails für Compliance-Zwecke. Das Loot System verwaltet Lootboxen, deren Belohnungen und die zugehörigen Wahrscheinlichkeitsverteilungen, wobei besonderer Wert auf Transparenz und Fairness gelegt wird.
\subsection{Deployment-Strategie}
Die Deployment-Strategie wurde so konzipiert, dass sie sowohl lokale Entwicklung als auch produktive Umgebungen unterstützt. Für die lokale Entwicklung wird Docker Compose\footnote{Docker Compose - \url{https://docs.docker.com/compose/}} eingesetzt, welches eine konsistente Entwicklungsumgebung über verschiedene Entwicklerrechner hinweg gewährleistet.
Frontend und Backend können unabhängig voneinander gebaut und deployed werden, was eine flexible Entwicklung und Wartung ermöglicht. Diese Entkopplung erlaubt es verschiedenen Teams, parallel zu arbeiten, ohne sich gegenseitig zu blockieren. Verschiedene Umgebungskonfigurationen durch Profile stellen sicher, dass entwicklungs- und produktionsspezifische Einstellungen sauber getrennt sind und automatisiert angewendet werden können.

View file

@ -0,0 +1,48 @@
% !TEX root = ../Projektdokumentation.tex
\section{Projektplanung}
\label{sec:Projektplanung}
\subsection{Projektphasen}
\label{sec:Projektphasen}
Für die Umsetzung des Projektes standen dem Autor 70 Stunden zur Verfügung. Zu Projektbeginn wurden diese auf, wie in der
Softwareentwicklung üblich, verschiedene Phasen verteilt, die während der Entwicklung durchlaufen werden.
Eine grobe Zeitplanung sowie die Hauptphasen lassen sich der Tabelle~\ref{tab:Zeitplanung} entnehmen.
Eine Pufferzeit wurde bereits in der Planung der Implementierung inkludiert.
Die Hauptphasen werden außerdem noch in kleinere Unterpunkte zerlegt. Eine detaillierte Übersicht der Phasen befindet sich im \Anhang{app:Zeitplanung}.
\tabelle{Zeitplanung}{tab:Zeitplanung}{ZeitplanungKurz}\\
\subsection{Ressourcenplanung}
\label{sec:Ressourcenplanung}
Eine genaue Auflistung der verwendeten Ressourcen, welche für das Projekt eingesetzt wurden, kann der Übersicht im
\Anhang{app:Ressourcen} entnommen werden. Hiermit sind sowohl Hard- und Softwareressourcen als auch Personal vom Autor berücksichtigt worden.
Bei der Auswahl der verwendeten Software wurde darauf geachtet, dass diese kostenfrei (\zB als Open Source) zur Verfügung
steht oder die \ac{NSD} bereits Lizenzen für diese besitzt. Hierdurch sollen anfallende Projektkosten so gering wie möglich
gehalten werden.
\subsection{Entwicklungsprozess}
\label{sec:Entwicklungsprozess}
Bevor mit der Realisierung des Projektes begonnen werden konnte, musste sich der Autor für eine geeignete Vorgehensweise zur Umsetzung entscheiden.
Der Autor hat sich auf einen agilen Entwicklungsprozess festgelegt. Hierbei wird in Anlehnung
an das Vorgehensmodell Kanban \footnote{Wikipedia Kanban Definition - \url{https://en.wikipedia.org/wiki/Kanban}} gearbeitet, welches durch Elemente des Vorgehensmodells Scrum \footnote{Scrum.org - \url{https://www.scrum.org}} erweitert werden soll.
Die für Scrum typischen Iterationen der Projektphasen sowie die damit verbundene, stetige Rücksprache
mit den Stakeholdern sind einige Merkmale, die diesen agilen Entwicklungsprozess auszeichnen und in diesem Abschlussprojekt Anwendung finden.
Eine flexible Umsetzung der Anforderung wird durch die relativ kurzen Entwicklungszyklen ermöglicht. Hierdurch können den Mitarbeitern der \ac{NSD}
zeitnah Resultate präsentiert werden. Aufgrund dieser Tatsache wurde bei der Projektplanung in Abschnitt~\ref{sec:Projektphasen}: \nameref{sec:Projektphasen} für die Entwurfsphase
weniger Zeit eingeplant, da sich Teile dieser Phase erst im Laufe der Entwicklung der Anwendung ergeben.
Das stetige Feedback zur Anwendung, resultierend aus der engen Kommunikation mit den Mitarbeitern, gewährleistet eine bessere und flexiblere Reaktionsfähigkeit
auf Änderungswünsche. So können die Kollegen des Autors während der Entwicklung mit dem System vertraut gemacht werden, welches zur Folge den Vorteil bringt,
dass bei Projektabnahme und -einführung Zeit eingespart werden kann. Dies wurde vom Autor in der Zeitkalkulation bereits berücksichtigt.
Außerdem soll der agile Entwicklungsprozess durch die Praktik der testabgedeckten Entwicklung erweitert werden. Hierbei werden Softwaretests nach der Implementierung
des Quellcodes erstellt. Dies hat zum Vorteil, dass nachträgliche Änderungen immer das gleiche Endresultat in der Datenausgabe erwarten und erhöht somit die Wartbarkeit
der gesamten Anwendung.

View file

@ -0,0 +1,56 @@
\section{Slots}
\subsection{Was ist Slots?}
Das Spiel 'Slots' ist eine digitale Implementierung eines klassischen Spielautomaten. Spieler setzen einen Betrag und drehen die Walzen, um Kombinationen von Symbolen zu erhalten. Ziel ist es, drei gleiche Symbole auf der mittleren Gewinnlinie zu erzielen, um einen Gewinn basierend auf dem Multiplikator des Symbols zu erhalten. Das Spiel bietet eine einfache und intuitive Möglichkeit, Glücksspiel zu erleben.
\subsubsection{Zufallszahlengenerierung}
Zur Generierung der Walzenpositionen verwendet diese Implementierung die Standardklasse \texttt{java.util.Random}. Für jede der drei Walzen wird eine pseudo-zufällige Zahl zwischen 0 und der \texttt{REEL\_LENGTH} (32) generiert. Diese Zahlen bestimmen die Startposition jedes Walzenstreifens. Die Walzenstreifen selbst werden bei der Initialisierung des \texttt{SlotService} einmalig erstellt und dann zufällig gemischt, um eine faire Verteilung der Symbole zu gewährleisten.
\subsubsection{Symbole und Auszahlungen}
Das Slots-Spiel verwendet verschiedene Symbole, die jeweils einen spezifischen Auszahlungsmultiplikator und eine bestimmte Häufigkeit auf den Walzenstreifen haben. Die Symbole sind:
\begin{itemize}
\item \textbf{SEVEN:} Höchster Auszahlungsmultiplikator (\texttt{1000x}). Seltenstes Symbol auf den Walzen.
\item \textbf{BAR:} Hoher Auszahlungsmultiplikator (\texttt{85x}).
\item \textbf{BELL:} Mittlerer Auszahlungsmultiplikator (\texttt{40x}).
\item \textbf{CHERRY:} Niedriger Auszahlungsmultiplikator (\texttt{10x}). Häufiger auf den Walzen.
\item \textbf{BLANK:} Kein Auszahlungsmultiplikator (\texttt{0x}). Dient als Platzhalter und führt bei dreifachem Erscheinen zu keinem Gewinn.
\end{itemize}
Die genaue Verteilung der Symbole auf den Walzenstreifen (\texttt{REEL\_LENGTH = 32}) ist wie folgt:
\begin{itemize}
\item SEVEN: 1 Vorkommen
\item BAR: 4 Vorkommen
\item BELL: 7 Vorkommen
\item CHERRY: 10 Vorkommen
\item BLANK: 10 Vorkommen
\end{itemize}
\subsubsection{Spielablauf und Datenfluss}
Der zentrale \texttt{SlotController} steuert den Spielablauf und empfängt die Anfragen vom Frontend. Jede Anfrage zum Drehen der Walzen (\texttt{/slots/spin}) enthält die Eckdaten des gewünschten Spins:
\begin{itemize}
\item \textbf{Einsatz:} Der gesetzte Münzbetrag.
\end{itemize}
Zuerst prüft der Controller das Guthaben des Spielers. Bei unzureichenden Mitteln wird der Vorgang abgelehnt. Andernfalls übergibt er die weitere Ausführung an die Dienstklasse (\texttt{SlotService}).
Die Dienstklasse (\texttt{SlotService}) übernimmt die eigentliche Logik des Slots-Spiels:
\begin{enumerate}
\item Zieht den Einsatz vom Spielerkonto ab.
\item Generiert zufällige Startpositionen für jede der drei Walzen.
\item Ermittelt die Symbole auf der mittleren Gewinnlinie basierend auf den generierten Positionen.
\item Bestimmt den Status des Spins (\texttt{WIN}, \texttt{LOSE}, \texttt{BLANK}) basierend auf den ermittelten Symbolen:
\begin{itemize}
\item \texttt{WIN}: Alle drei Symbole auf der Gewinnlinie sind identisch und keines davon ist \texttt{BLANK}.
\item \texttt{BLANK}: Alle drei Symbole auf der Gewinnlinie sind identisch und es handelt sich um \texttt{BLANK}-Symbole. Dies führt zu keinem Gewinn.
\item \texttt{LOSE}: Die Symbole auf der Gewinnlinie sind nicht alle identisch.
\end{itemize}
\item Berechnet den Gewinnbetrag bei einem \texttt{WIN}-Status (Einsatz $\times$ Auszahlungsmultiplikator des Gewinnsymbols) und schreibt ihn dem Spielerkonto gut. Bei \texttt{LOSE} oder \texttt{BLANK} wird kein Betrag gutgeschrieben.
\item Erstellt eine 3x3-Matrix der sichtbaren Symbole auf den Walzen, zentriert um die Gewinnlinie.
\end{enumerate}
Das Ergebnis des Spiels wird an das Frontend zurückgesendet und enthält:
\begin{itemize}
\item \textbf{Status:} Der Status des Spins (\texttt{win}, \texttt{lose}, \texttt{blank}).
\item \textbf{Amount:} Der gewonnene Betrag (bei \texttt{WIN}) oder der Einsatz (bei \texttt{LOSE}/\texttt{BLANK}).
\item \textbf{Result Matrix:} Eine 3x3-Matrix der Symbole, die auf den Walzen sichtbar sind.
\end{itemize}

View file

@ -0,0 +1,98 @@
[![Creative Commons Lizenzvertrag](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/)
LaTeX-Vorlage zur IHK-Projektdokumentation für Fachinformatiker Anwendungsentwicklung von [Stefan Macke](http://fiae.link/LaTeXVorlageFIAE) ist lizenziert unter einer [Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz](http://creativecommons.org/licenses/by-sa/4.0/).
### _Lizenz_
DER GEGENSTAND DIESER LIZENZ (WIE UNTER "SCHUTZGEGENSTAND" DEFINIERT) WIRD UNTER DEN BEDINGUNGEN DIESER CREATIVE COMMONS PUBLIC LICENSE ("CCPL", "LIZENZ" ODER "LIZENZVERTRAG") ZUR VERFÜGUNG GESTELLT. DER SCHUTZGEGENSTAND IST DURCH DAS URHEBERRECHT UND/ODER ANDERE GESETZE GESCHÜTZT. JEDE FORM DER NUTZUNG DES SCHUTZGEGENSTANDES, DIE NICHT AUFGRUND DIESER LIZENZ ODER DURCH GESETZE GESTATTET IST, IST UNZULÄSSIG.
DURCH DIE AUSÜBUNG EINES DURCH DIESE LIZENZ GEWÄHRTEN RECHTS AN DEM SCHUTZGEGENSTAND ERKLÄREN SIE SICH MIT DEN LIZENZBEDINGUNGEN RECHTSVERBINDLICH EINVERSTANDEN. SOWEIT DIESE LIZENZ ALS LIZENZVERTRAG ANZUSEHEN IST, GEWÄHRT IHNEN DER LIZENZGEBER DIE IN DER LIZENZ GENANNTEN RECHTE UNENTGELTLICH UND IM AUSTAUSCH DAFÜR, DASS SIE DAS GEBUNDENSEIN AN DIE LIZENZBEDINGUNGEN AKZEPTIEREN.
**1\. Definitionen**
1. Der Begriff "**Abwandlung**" im Sinne dieser Lizenz bezeichnet das Ergebnis jeglicher Art von Veränderung des Schutzgegenstandes, solange die eigenpersönlichen Züge des Schutzgegenstandes darin nicht verblassen und daran eigene Schutzrechte entstehen. Das kann insbesondere eine Bearbeitung, Umgestaltung, Änderung, Anpassung, Übersetzung oder Heranziehung des Schutzgegenstandes zur Vertonung von Laufbildern sein. Nicht als Abwandlung des Schutzgegenstandes gelten seine Aufnahme in eine Sammlung oder ein Sammelwerk und die freie Benutzung des Schutzgegenstandes.
2. Der Begriff "**Sammelwerk**" im Sinne dieser Lizenz meint eine Zusammenstellung von literarischen, künstlerischen oder wissenschaftlichen Inhalten, sofern diese Zusammenstellung aufgrund von Auswahl und Anordnung der darin enthaltenen selbständigen Elemente eine geistige Schöpfung darstellt, unabhängig davon, ob die Elemente systematisch oder methodisch angelegt und dadurch einzeln zugänglich sind oder nicht.
3. "**Verbreiten**" im Sinne dieser Lizenz bedeutet, den Schutzgegenstand oder Abwandlungen im Original oder in Form von Vervielfältigungsstücken, mithin in körperlich fixierter Form der Öffentlichkeit anzubieten oder in Verkehr zu bringen.
4. Unter "**Lizenzelementen**" werden im Sinne dieser Lizenz die folgenden übergeordneten Lizenzcharakteristika verstanden, die vom Lizenzgeber ausgewählt wurden und in der Bezeichnung der Lizenz zum Ausdruck kommen: "Namensnennung", "Weitergabe unter gleichen Bedingungen".
5. Der "**Lizenzgeber**" im Sinne dieser Lizenz ist diejenige natürliche oder juristische Person oder Gruppe, die den Schutzgegenstand unter den Bedingungen dieser Lizenz anbietet und insoweit als Rechteinhaberin auftritt.
6. "**Rechteinhaber**" im Sinne dieser Lizenz ist der Urheber des Schutzgegenstandes oder jede andere natürliche oder juristische Person oder Gruppe von Personen, die am Schutzgegenstand ein Immaterialgüterrecht erlangt hat, welches die in Abschnitt 3 genannten Handlungen erfasst und bei dem eine Einräumung von Nutzungsrechten oder eine Weiterübertragung an Dritte möglich ist.
7. Der Begriff "**Schutzgegenstand**" bezeichnet in dieser Lizenz den literarischen, künstlerischen oder wissenschaftlichen Inhalt, der unter den Bedingungen dieser Lizenz angeboten wird. Das kann insbesondere eine persönliche geistige Schöpfung jeglicher Art, ein Werk der kleinen Münze, ein nachgelassenes Werk oder auch ein Lichtbild oder anderes Objekt eines verwandten Schutzrechts sein, unabhängig von der Art seiner Fixierung und unabhängig davon, auf welche Weise jeweils eine Wahrnehmung erfolgen kann, gleichviel ob in analoger oder digitaler Form. Soweit Datenbanken oder Zusammenstellungen von Daten einen immaterialgüterrechtlichen Schutz eigener Art genießen, unterfallen auch sie dem Begriff "Schutzgegenstand" im Sinne dieser Lizenz.
8. Mit "**Sie**" bzw. "**Ihnen**" ist die natürliche oder juristische Person gemeint, die in dieser Lizenz im Abschnitt 3 genannte Nutzungen des Schutzgegenstandes vornimmt und zuvor in Hinblick auf den Schutzgegenstand nicht gegen Bedingungen dieser Lizenz verstoßen oder aber die ausdrückliche Erlaubnis des Lizenzgebers erhalten hat, die durch diese Lizenz gewährten Nutzungsrechte trotz eines vorherigen Verstoßes auszuüben.
9. Unter "**Öffentlich Zeigen**" im Sinne dieser Lizenz sind Veröffentlichungen und Präsentationen des Schutzgegenstandes zu verstehen, die für eine Mehrzahl von Mitgliedern der Öffentlichkeit bestimmt sind und in unkörperlicher Form mittels öffentlicher Wiedergabe in Form von Vortrag, Aufführung, Vorführung, Darbietung, Sendung, Weitersendung, zeit- und ortsunabhängiger Zugänglichmachung oder in körperlicher Form mittels Ausstellung erfolgen, unabhängig von bestimmten Veranstaltungen und unabhängig von den zum Einsatz kommenden Techniken und Verfahren, einschließlich drahtgebundener oder drahtloser Mittel und Einstellen in das Internet.
10. "**Vervielfältigen**" im Sinne dieser Lizenz bedeutet, mittels beliebiger Verfahren Vervielfältigungsstücke des Schutzgegenstandes herzustellen, insbesondere durch Ton- oder Bildaufzeichnungen, und umfasst auch den Vorgang, erstmals körperliche Fixierungen des Schutzgegenstandes sowie Vervielfältigungsstücke dieser Fixierungen anzufertigen, sowie die Übertragung des Schutzgegenstandes auf einen Bild- oder Tonträger oder auf ein anderes elektronisches Medium, gleichviel ob in digitaler oder analoger Form.
11. "**Mit Creative Commons kompatible Lizenz**" bezeichnet eine Lizenz, die unter https://creativecommons.org/compatiblelicenses aufgelistet ist und die durch Creative Commons als grundsätzlich zur vorliegenden Lizenz äquivalent akzeptiert wurde, da zumindest folgende Voraussetzungen erfüllt sind:
Diese mit Creative Commons kompatible Lizenz
1. enthält Bestimmungen, welche die gleichen Ziele verfolgen, die gleiche Bedeutung haben und die gleichen Wirkungen erzeugen wie die Lizenzelemente der vorliegenden Lizenz; und
2. erlaubt ausdrücklich das Lizenzieren von ihr unterstellten Abwandlungen unter vorliegender Lizenz, unter einer anderen rechtsordnungsspezifisch angepassten Creative-Commons-Lizenz mit denselben Lizenzelementen, wie sie die vorliegende Lizenz aufweist, oder unter der entsprechenden Creative-Commons-Unported-Lizenz.
**2\. Schranken des Immaterialgüterrechts**
Diese Lizenz ist in keiner Weise darauf gerichtet, Befugnisse zur Nutzung des Schutzgegenstandes zu vermindern, zu beschränken oder zu vereiteln, die Ihnen aufgrund der Schranken des Urheberrechts oder anderer Rechtsnormen bereits ohne Weiteres zustehen oder sich aus dem Fehlen eines immaterialgüterrechtlichen Schutzes ergeben.
**3\. Einräumung von Nutzungsrechten**
Unter den Bedingungen dieser Lizenz räumt Ihnen der Lizenzgeber - unbeschadet unverzichtbarer Rechte und vorbehaltlich des Abschnitts 3.e) - das vergütungsfreie, räumlich und zeitlich (für die Dauer des Schutzrechts am Schutzgegenstand) unbeschränkte einfache Recht ein, den Schutzgegenstand auf die folgenden Arten und Weisen zu nutzen ("unentgeltlich eingeräumtes einfaches Nutzungsrecht für jedermann"):
1. Den Schutzgegenstand in beliebiger Form und Menge zu vervielfältigen, ihn in Sammelwerke zu integrieren und ihn als Teil solcher Sammelwerke zu vervielfältigen;
2. Abwandlungen des Schutzgegenstandes anzufertigen, einschließlich Übersetzungen unter Nutzung jedweder Medien, sofern deutlich erkennbar gemacht wird, dass es sich um Abwandlungen handelt;
3. den Schutzgegenstand, allein oder in Sammelwerke aufgenommen, öffentlich zu zeigen und zu verbreiten;
4. Abwandlungen des Schutzgegenstandes zu veröffentlichen, öffentlich zu zeigen und zu verbreiten.
5. Bezüglich Vergütung für die Nutzung des Schutzgegenstandes gilt Folgendes:
1. **Unverzichtbare gesetzliche Vergütungsansprüche**: Soweit unverzichtbare Vergütungsansprüche im Gegenzug für gesetzliche Lizenzen vorgesehen oder Pauschalabgabensysteme (zum Beispiel für Leermedien) vorhanden sind, behält sich der Lizenzgeber das ausschließliche Recht vor, die entsprechende Vergütung einzuziehen für jede Ausübung eines Rechts aus dieser Lizenz durch Sie.
2. **Vergütung bei Zwangslizenzen**: Sofern Zwangslizenzen außerhalb dieser Lizenz vorgesehen sind und zustande kommen, verzichtet der Lizenzgeber für alle Fälle einer lizenzgerechten Nutzung des Schutzgegenstandes durch Sie auf jegliche Vergütung.
3. **Vergütung in sonstigen Fällen**: Bezüglich lizenzgerechter Nutzung des Schutzgegenstandes durch Sie, die nicht unter die beiden vorherigen Abschnitte (i) und (ii) fällt, verzichtet der Lizenzgeber auf jegliche Vergütung, unabhängig davon, ob eine Einziehung der Vergütung durch ihn selbst oder nur durch eine Verwertungsgesellschaft möglich wäre.
Das vorgenannte Nutzungsrecht wird für alle bekannten sowie für alle noch nicht bekannten Nutzungsarten eingeräumt. Es beinhaltet auch das Recht, solche Änderungen am Schutzgegenstand vorzunehmen, die für bestimmte nach dieser Lizenz zulässige Nutzungen technisch erforderlich sind. Alle sonstigen Rechte, die über diesen Abschnitt hinaus nicht ausdrücklich durch den Lizenzgeber eingeräumt werden, bleiben diesem allein vorbehalten. Soweit Datenbanken oder Zusammenstellungen von Daten Schutzgegenstand dieser Lizenz oder Teil dessen sind und einen immaterialgüterrechtlichen Schutz eigener Art genießen, verzichtet der Lizenzgeber auf sämtliche aus diesem Schutz resultierenden Rechte.
**4\. Bedingungen**
Die Einräumung des Nutzungsrechts gemäß Abschnitt 3 dieser Lizenz erfolgt ausdrücklich nur unter den folgenden Bedingungen:
1. Sie dürfen den Schutzgegenstand ausschließlich unter den Bedingungen dieser Lizenz verbreiten oder öffentlich zeigen. Sie müssen dabei stets eine Kopie dieser Lizenz oder deren vollständige Internetadresse in Form des Uniform-Resource-Identifier (URI) beifügen. Sie dürfen keine Vertrags- oder Nutzungsbedingungen anbieten oder fordern, die die Bedingungen dieser Lizenz oder die durch diese Lizenz gewährten Rechte beschränken. Sie dürfen den Schutzgegenstand nicht unterlizenzieren. Bei jeder Kopie des Schutzgegenstandes, die Sie verbreiten oder öffentlich zeigen, müssen Sie alle Hinweise unverändert lassen, die auf diese Lizenz und den Haftungsausschluss hinweisen. Wenn Sie den Schutzgegenstand verbreiten oder öffentlich zeigen, dürfen Sie (in Bezug auf den Schutzgegenstand) keine technischen Maßnahmen ergreifen, die den Nutzer des Schutzgegenstandes in der Ausübung der ihm durch diese Lizenz gewährten Rechte behindern können. Dieser Abschnitt 4.a) gilt auch für den Fall, dass der Schutzgegenstand einen Bestandteil eines Sammelwerkes bildet, was jedoch nicht bedeutet, dass das Sammelwerk insgesamt dieser Lizenz unterstellt werden muss. Sofern Sie ein Sammelwerk erstellen, müssen Sie auf die Mitteilung eines Lizenzgebers hin aus dem Sammelwerk die in Abschnitt 4.c) aufgezählten Hinweise entfernen. Wenn Sie eine Abwandlung vornehmen, müssen Sie auf die Mitteilung eines Lizenzgebers hin von der Abwandlung die in Abschnitt 4.c) aufgezählten Hinweise entfernen.
2. Sie dürfen eine Abwandlung ausschließlich unter den Bedingungen
1. dieser Lizenz,
2. einer späteren Version dieser Lizenz mit denselben Lizenzelementen,
3. einer rechtsordnungsspezifischen Creative-Commons-Lizenz mit denselben Lizenzelementen ab Version 3.0 aufwärts (z.B. Namensnennung - Weitergabe unter gleichen Bedingungen 3.0 US),
4. der Creative-Commons-Unported-Lizenz mit denselben Lizenzelementen ab Version 3.0 aufwärts, oder
5. einer mit Creative Commons kompatiblen Lizenz
verbreiten oder öffentlich zeigen.
Falls Sie die Abwandlung gemäß Abschnitt (v) unter einer mit Creative Commons kompatiblen Lizenz lizenzieren, müssen Sie deren Lizenzbestimmungen Folge leisten.
Falls Sie die Abwandlungen unter einer der unter (i)-(iv) genannten Lizenzen ("Verwendbare Lizenzen") lizenzieren, müssen Sie deren Lizenzbestimmungen sowie folgenden Bestimmungen Folge leisten: Sie müssen stets eine Kopie der verwendbaren Lizenz oder deren vollständige Internetadresse in Form des Uniform-Resource-Identifier (URI) beifügen, wenn Sie die Abwandlung verbreiten oder öffentlich zeigen. Sie dürfen keine Vertrags- oder Nutzungsbedingungen anbieten oder fordern, die die Bedingungen der verwendbaren Lizenz oder die durch sie gewährten Rechte beschränken. Bei jeder Abwandlung, die Sie verbreiten oder öffentlich zeigen, müssen Sie alle Hinweise auf die verwendbare Lizenz und den Haftungsausschluss unverändert lassen. Wenn Sie die Abwandlung verbreiten oder öffentlich zeigen, dürfen Sie (in Bezug auf die Abwandlung) keine technischen Maßnahmen ergreifen, die den Nutzer der Abwandlung in der Ausübung der ihm durch die verwendbare Lizenz gewährten Rechte behindern können. Dieser Abschnitt 4.b) gilt auch für den Fall, dass die Abwandlung einen Bestandteil eines Sammelwerkes bildet, was jedoch nicht bedeutet, dass das Sammelwerk insgesamt der verwendbaren Lizenz unterstellt werden muss.
3. Die Verbreitung und das öffentliche Zeigen des Schutzgegenstandes oder auf ihm aufbauender Abwandlungen oder ihn enthaltender Sammelwerke ist Ihnen nur unter der Bedingung gestattet, dass Sie, vorbehaltlich etwaiger Mitteilungen im Sinne von Abschnitt 4.a), alle dazu gehörenden Rechtevermerke unberührt lassen. Sie sind verpflichtet, die Rechteinhaberschaft in einer der Nutzung entsprechenden, angemessenen Form anzuerkennen, indem Sie - soweit bekannt - Folgendes angeben:
1. Den Namen (oder das Pseudonym, falls ein solches verwendet wird) des Rechteinhabers und / oder, falls der Lizenzgeber im Rechtevermerk, in den Nutzungsbedingungen oder auf andere angemessene Weise eine Zuschreibung an Dritte vorgenommen hat (z.B. an eine Stiftung, ein Verlagshaus oder eine Zeitung) ("Zuschreibungsempfänger"), Namen bzw. Bezeichnung dieses oder dieser Dritten;
2. den Titel des Inhaltes;
3. in einer praktikablen Form den Uniform-Resource-Identifier (URI, z.B. Internetadresse), den der Lizenzgeber zum Schutzgegenstand angegeben hat, es sei denn, dieser URI verweist nicht auf den Rechtevermerk oder die Lizenzinformationen zum Schutzgegenstand;
4. und im Falle einer Abwandlung des Schutzgegenstandes in Übereinstimmung mit Abschnitt 3.b) einen Hinweis darauf, dass es sich um eine Abwandlung handelt.
Die nach diesem Abschnitt 4.c) erforderlichen Angaben können in jeder angemessenen Form gemacht werden; im Falle einer Abwandlung des Schutzgegenstandes oder eines Sammelwerkes müssen diese Angaben das Minimum darstellen und bei gemeinsamer Nennung mehrerer Rechteinhaber dergestalt erfolgen, dass sie zumindest ebenso hervorgehoben sind wie die Hinweise auf die übrigen Rechteinhaber. Die Angaben nach diesem Abschnitt dürfen Sie ausschließlich zur Angabe der Rechteinhaberschaft in der oben bezeichneten Weise verwenden. Durch die Ausübung Ihrer Rechte aus dieser Lizenz dürfen Sie ohne eine vorherige, separat und schriftlich vorliegende Zustimmung des Lizenzgebers und / oder des Zuschreibungsempfängers weder explizit noch implizit irgendeine Verbindung zum Lizenzgeber oder Zuschreibungsempfänger und ebenso wenig eine Unterstützung oder Billigung durch ihn andeuten.
4. Die oben unter 4.a) bis c) genannten Einschränkungen gelten nicht für solche Teile des Schutzgegenstandes, die allein deshalb unter den Schutzgegenstandsbegriff fallen, weil sie als Datenbanken oder Zusammenstellungen von Daten einen immaterialgüterrechtlichen Schutz eigener Art genießen.
5. Persönlichkeitsrechte bleiben - soweit sie bestehen - von dieser Lizenz unberührt.
**5\. Gewährleistung**
SOFERN KEINE ANDERS LAUTENDE, SCHRIFTLICHE VEREINBARUNG ZWISCHEN DEM LIZENZGEBER UND IHNEN GESCHLOSSEN WURDE UND SOWEIT MÄNGEL NICHT ARGLISTIG VERSCHWIEGEN WURDEN, BIETET DER LIZENZGEBER DEN SCHUTZGEGENSTAND UND DIE EINRÄUMUNG VON RECHTEN UNTER AUSSCHLUSS JEGLICHER GEWÄHRLEISTUNG AN UND ÜBERNIMMT WEDER AUSDRÜCKLICH NOCH KONKLUDENT GARANTIEN IRGENDEINER ART. DIES UMFASST INSBESONDERE DAS FREISEIN VON SACH- UND RECHTSMÄNGELN, UNABHÄNGIG VON DEREN ERKENNBARKEIT FÜR DEN LIZENZGEBER, DIE VERKEHRSFÄHIGKEIT DES SCHUTZGEGENSTANDES, SEINE VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK SOWIE DIE KORREKTHEIT VON BESCHREIBUNGEN. DIESE GEWÄHRLEISTUNGSBESCHRÄNKUNG GILT NICHT, SOWEIT MÄNGEL ZU SCHÄDEN DER IN ABSCHNITT 6 BEZEICHNETEN ART FÜHREN UND AUF SEITEN DES LIZENZGEBERS DAS JEWEILS GENANNTE VERSCHULDEN BZW. VERTRETENMÜSSEN EBENFALLS VORLIEGT.
**6\. Haftungsbeschränkung**
DER LIZENZGEBER HAFTET IHNEN GEGENÜBER IN BEZUG AUF SCHÄDEN AUS DER VERLETZUNG DES LEBENS, DES KÖRPERS ODER DER GESUNDHEIT NUR, SOFERN IHM WENIGSTENS FAHRLÄSSIGKEIT VORZUWERFEN IST, FÜR SONSTIGE SCHÄDEN NUR BEI GROBER FAHRLÄSSIGKEIT ODER VORSATZ, UND ÜBERNIMMT DARÜBER HINAUS KEINERLEI FREIWILLIGE HAFTUNG.
**7\. Erlöschen**
1. Diese Lizenz und die durch sie eingeräumten Nutzungsrechte erlöschen mit Wirkung für die Zukunft im Falle eines Verstoßes gegen die Lizenzbedingungen durch Sie, ohne dass es dazu der Kenntnis des Lizenzgebers vom Verstoß oder einer weiteren Handlung einer der Vertragsparteien bedarf. Mit natürlichen oder juristischen Personen, die Abwandlungen des Schutzgegenstandes oder diesen enthaltende Sammelwerke unter den Bedingungen dieser Lizenz von Ihnen erhalten haben, bestehen nachträglich entstandene Lizenzbeziehungen jedoch solange weiter, wie die genannten Personen sich ihrerseits an sämtliche Lizenzbedingungen halten. Darüber hinaus gelten die Ziffern 1, 2, 5, 6, 7, und 8 auch nach einem Erlöschen dieser Lizenz fort.
2. Vorbehaltlich der oben genannten Bedingungen gilt diese Lizenz unbefristet bis der rechtliche Schutz für den Schutzgegenstand ausläuft. Davon abgesehen behält der Lizenzgeber das Recht, den Schutzgegenstand unter anderen Lizenzbedingungen anzubieten oder die eigene Weitergabe des Schutzgegenstandes jederzeit einzustellen, solange die Ausübung dieses Rechts nicht einer Kündigung oder einem Widerruf dieser Lizenz (oder irgendeiner Weiterlizenzierung, die auf Grundlage dieser Lizenz bereits erfolgt ist bzw. zukünftig noch erfolgen muss) dient und diese Lizenz unter Berücksichtigung der oben zum Erlöschen genannten Bedingungen vollumfänglich wirksam bleibt.
**8\. Sonstige Bestimmungen**
1. Jedes Mal wenn Sie den Schutzgegenstand für sich genommen oder als Teil eines Sammelwerkes verbreiten oder öffentlich zeigen, bietet der Lizenzgeber dem Empfänger eine Lizenz zu den gleichen Bedingungen und im gleichen Umfang an, wie Ihnen in Form dieser Lizenz.
2. Jedes Mal wenn Sie eine Abwandlung des Schutzgegenstandes verbreiten oder öffentlich zeigen, bietet der Lizenzgeber dem Empfänger eine Lizenz am ursprünglichen Schutzgegenstand zu den gleichen Bedingungen und im gleichen Umfang an, wie Ihnen in Form dieser Lizenz.
3. Sollte eine Bestimmung dieser Lizenz unwirksam sein, so bleibt davon die Wirksamkeit der Lizenz im Übrigen unberührt.
4. Keine Bestimmung dieser Lizenz soll als abbedungen und kein Verstoß gegen sie als zulässig gelten, solange die von dem Verzicht oder von dem Verstoß betroffene Seite nicht schriftlich zugestimmt hat.
5. Diese Lizenz (zusammen mit in ihr ausdrücklich vorgesehenen Erlaubnissen, Mitteilungen und Zustimmungen, soweit diese tatsächlich vorliegen) stellt die vollständige Vereinbarung zwischen dem Lizenzgeber und Ihnen in Bezug auf den Schutzgegenstand dar. Es bestehen keine Abreden, Vereinbarungen oder Erklärungen in Bezug auf den Schutzgegenstand, die in dieser Lizenz nicht genannt sind. Rechtsgeschäftliche Änderungen des Verhältnisses zwischen dem Lizenzgeber und Ihnen sind nur über Modifikationen dieser Lizenz möglich. Der Lizenzgeber ist an etwaige zusätzliche, einseitig durch Sie übermittelte Bestimmungen nicht gebunden. Diese Lizenz kann nur durch schriftliche Vereinbarung zwischen Ihnen und dem Lizenzgeber modifiziert werden. Derlei Modifikationen wirken ausschließlich zwischen dem Lizenzgeber und Ihnen und wirken sich nicht auf die Dritten gemäß Ziffern 8.a) und b) angeboteten Lizenzen aus.
6. Sofern zwischen Ihnen und dem Lizenzgeber keine anderweitige Vereinbarung getroffen wurde und soweit Wahlfreiheit besteht, findet auf diesen Lizenzvertrag das Recht der Bundesrepublik Deutschland Anwendung.

View file

@ -0,0 +1,139 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection\Model;
use GuzzleHttp\Exception\RequestException;
use Psr\Http\Message\ResponseInterface;
use Psr\Log\LoggerInterface;
use Neusta\IntexClientConfig\Model\Config\Config;
use Neusta\IntexClientConfig\Provider\JsonConfigProvider;
use \GuzzleHttp\Client as GuzzleHttpClient;
use \GuzzleHttp\Event\BeforeEvent;
use \GuzzleHttp\Event\CompleteEvent;
use function sprintf;
abstract class Connection
{
protected const HTTP_STATUS_CODE_OK = 200;
/**
* @var GuzzleHttpClient
*/
protected $httpClient;
/**
* @var Config
*/
protected $serverConfig;
/**
* @var LoggerInterface
*/
protected $logger;
public function __construct(JsonConfigProvider $configProvider, LoggerInterface $logger)
{
$this->logger = $logger;
$this->serverConfig = $configProvider->getConfig('server');
$this->httpClient = new GuzzleHttpClient(
$this->getHttpClientOptions()
);
$this->initHttpEventEmitter();
}
protected function authenticate(): bool
{
$result = false;
$response = $this->createPost(
$this->serverConfig->getAuthUri()
);
$statusCode = $response->getStatusCode();
if ($statusCode === self::HTTP_STATUS_CODE_OK) {
$this->logger->info('authentication successful');
$result = true;
} else {
$this->logger->info(
sprintf('authentication failed with Code: %s', $statusCode)
);
}
return $result;
}
protected function createPost(string $uri, array $options = []): ?ResponseInterface
{
$result = null;
$request = $this->httpClient->postAsync($uri, $options);
$request->then(
static function (ResponseInterface $response) {
$result = $response;
},
function (RequestException $exception) {
$this->logger->info(
sprintf('Crucial Error: %s \n Trace: %u', $exception->getMessage(), $exception->getTraceAsString())
);
}
);
return $result;
}
protected function createGet(string $uri, array $options = []): ?ResponseInterface
{
$result = null;
$request = $this->httpClient->getAsync($uri, $options);
$request->then(
static function (ResponseInterface $response) {
$result = $response;
},
function (RequestException $exception) {
$this->logger->info(
sprintf('Crucial Error: %s \n Trace: %u', $exception->getMessage(), $exception->getTraceAsString())
);
}
);
return $result;
}
protected function initHttpEventEmitter(): void
{
// initialize the EventEmitters to get a good Logging whether the Request was send
// or failed
$this->httpClient->getEmitter()->on('before', static function (BeforeEvent $event) {
$this->logger->info(
sprintf('About to send Request: %s', $event->getRequest())
);
});
$this->httpClient->getEmitter()->on('complete', static function (CompleteEvent $event) {
$this->logger->info(
sprintf('Request %s finished', $event->getRequest())
);
});
$this->httpClient->getEmitter()->on('error', static function (ErrorEvent $event) {
$this->logger->info(
sprintf('Request %s failed', $event->getRequest())
);
});
}
protected function getHttpClientOptions(): array
{
// Configure Base URL for all ongoing Requests and set Cookies to true,
// so we can handle the auth cookie over and over again without using authenticate() multiple times
return [
'base_url' => $this->serverConfig->getBaseUrl(),
'cookies' => true
];
}
}

View file

@ -0,0 +1,33 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection\Model;
use Neusta\IntexClientConfig\Model\Config\Config;
use Neusta\IntexClientConfig\Provider\JsonConfigProvider;
use Psr\Log\LoggerInterface;
use function json_decode;
class CustomerConnection extends Connection
{
/**
* @var Config
*/
private $customerConfig;
public function __construct(JsonConfigProvider $configProvider, LoggerInterface $logger)
{
parent::__construct($configProvider, $logger);
$this->customerConfig = $configProvider->getConfig('customer');
}
public function loadCustomerData(): array
{
$response = $this->createGet(
$this->customerConfig->getCustomerUri()
);
return json_decode($response->getBody(), true);
}
}

View file

@ -0,0 +1,28 @@
<?php declare(strict_types=1);
namespace Neusta\IntexCustomer\Controller;
use Neusta\IntexClient\Connection\Model\CustomerConnection;
class CustomerDataController
{
/**
* @var CustomerConnection
*/
private $connection;
public function __construct(\Neusta\IntexClient\Connection\Factory $connectionFactory, \Neusta\IntexCustomer\Handler\DataHandler $dataHandler)
{
$this->connection = $connectionFactory->create('customer');
$this->customerDataHandler = $dataHandler;
}
public function getCustomerData(): void
{
$customerData = $this->connection->loadCustomerData();
$this->customerDataHandler->saveCustomerData($customerData);
}
}

View file

@ -0,0 +1,27 @@
<?php declare(strict_types=1);
namespace Neusta\IntexClient\Connection;
use Neusta\IntexClient\Connection\Model\Connection;
use function class_exists;
use function sprintf;
use function ucwords;
use function strtolower;
class Factory
{
public static function create(string $connectionType): Connection
{
$connectionPath = sprintf(
'\Neusta\IntexClient\Model\Connection\%sConnection',
ucwords(strtolower($connectionType))
);
if (class_exists($connectionPath)) {
return new $connectionPath();
}
throw new \RuntimeException('Invalid Connection Type given');
}
}

View file

@ -0,0 +1,28 @@
<?xml version="1.0" ?>
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="neusta_intex_import" resource="default" engine="innodb"
comment="Neusta IntexImport Logging Table">
<column xsi:type="int" name="value_id" padding="11" unsigned="false" nullable="false" identity="true" comment="Value ID"/>
<column xsi:type="smallint" name="attribute_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Attribute ID"/>
<column xsi:type="smallint" name="store_id" padding="5" unsigned="true" nullable="false" identity="false" default="0" comment="Store ID"/>
<column xsi:type="int" name="entity_id" padding="10" unsigned="true" nullable="false" identity="false" default="0" comment="Entity ID"/>
<column xsi:type="datetime" name="value" on_update="false" nullable="true" comment="Value"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="value_id"/>
</constraint>
<constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ATTR_ID_EAV_ATTR_ATTR_ID" table="catalog_product_entity_datetime" column="attribute_id" referenceTable="eav_attribute" referenceColumn="attribute_id" onDelete="CASCADE"/>
<constraint xsi:type="foreign" referenceId="CAT_PRD_ENTT_DTIME_ENTT_ID_CAT_PRD_ENTT_ENTT_ID" table="catalog_product_entity_datetime" column="entity_id" referenceTable="catalog_product_entity" referenceColumn="entity_id" onDelete="CASCADE"/>
<constraint xsi:type="foreign" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID_STORE_STORE_ID" table="catalog_product_entity_datetime" column="store_id" referenceTable="store" referenceColumn="store_id" onDelete="CASCADE"/>
<constraint xsi:type="unique" referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ENTITY_ID_ATTRIBUTE_ID_STORE_ID">
<column name="entity_id"/>
<column name="attribute_id"/>
<column name="store_id"/>
</constraint>
<index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_ATTRIBUTE_ID" indexType="btree">
<column name="attribute_id"/>
</index>
<index referenceId="CATALOG_PRODUCT_ENTITY_DATETIME_STORE_ID" indexType="btree">
<column name="store_id"/>
</index>
</table>
</schema>

View file

@ -0,0 +1,39 @@
<?php declare(strict_types=1);
use PHPUnit\Framework\TestCase;
use Neusta\IntexClient\Connection\Factory;
use Neusta\IntexClient\Connection\Model\CustomerConnection;
class FactoryTest extends TestCase
{
/**
* @var Factory
*/
private $subject;
public function setUp()
{
$this->subject = new Factory();
}
/**
* @test
*/
public function createMustReturnInstanceOfCustomerConnectionWithValidIdentifierGiven()
{
$expectedInstance = $this->subject->create('customer');
self::assertInstanceOf(CustomerConnection::class, $expectedInstance);
}
/**
* @test
* @throws RuntimeException
*/
public function createMustThrowRuntimeExceptionIfInvalidIdentifierIsGiven()
{
$unexpectedInstance = $this->subject->create('fooBar');
self::expectException(RuntimeException::class);
}
}

View file

@ -0,0 +1,21 @@
{
"name": "neusta/m2-intex-client",
"license": "proprietary",
"description": "Client for Magento2 Intex Import/Export",
"type": "magento2-module",
"version": "0.0.1",
"require": {
"php": "7.4.33",
"magento/framework": "~101.0",
"neusta/m2-intex-base": "0.0.1",
"guzzlehttp/guzzle": "6.5.*"
},
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Neusta\\IntexClient\\": "src"
}
}
}

View file

@ -0,0 +1,33 @@
<?php
include(dirname(__FILE__).'/../bootstrap/Propel.php');
$t = new lime_test(13);
$t->comment('Empty Information');
$emptyComparedInformation = new ComparedNaturalModuleInformation(array());
$t->is($emptyComparedInformation->getCatalogSign(), ComparedNaturalModuleInformation::EMPTY_SIGN, 'Has no catalog sign');
$t->is($emptyComparedInformation->getSourceSign(), ComparedNaturalModuleInformation::SIGN_CREATE, 'Source has to be created');
$t->comment('Perfect Module');
$criteria = new Criteria();
$criteria->add(NaturalmodulenamePeer::NAME, 'SMTAB');
$moduleName = NaturalmodulenamePeer::doSelectOne($criteria);
$t->is($moduleName->getName(), 'SMTAB', 'Right modulename selected');
$comparedInformation = $moduleName->loadNaturalModuleInformation();
$t->is($comparedInformation->getSourceSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Source sign shines global');
$t->is($comparedInformation->getCatalogSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Catalog sign shines global');
$infos = $comparedInformation->getNaturalModuleInformations();
foreach($infos as $info)
{
$env = $info->getEnvironmentName();
$t->is($info->getSourceSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Source sign shines at ' . $env);
if($env != 'SVNENTW')
{
$t->is($info->getCatalogSign(), ComparedNaturalModuleInformation::SIGN_OK, 'Catalog sign shines at ' . $info->getEnvironmentName());
}
else
{
$t->is($info->getCatalogSign(), ComparedNaturalModuleInformation::EMPTY_SIGN, 'Catalog sign is empty at ' . $info->getEnvironmentName());
}
}
?>

View file

@ -0,0 +1,14 @@
% !TEX root = Projektdokumentation.tex
% Hinweis: der Titel muss zum Inhalt des Projekts passen und den zentralen Inhalt des Projekts deutlich herausstellen
\newcommand{\titel}{Trustworthy Casino}
\newcommand{\untertitel}{Online-Spiele Casino}
\newcommand{\kompletterTitel}{\titel{} -- \untertitel}
\newcommand{\autorName}{Phan Huy Tran}
\newcommand{\betriebLogo}{hitec-logo.png}
\newcommand{\ausbildungsberuf}{Fachinformatiker für Anwendungsentwicklung}
\newcommand{\betreff}{Dokumentation}
\newcommand{\projektZeitraum}{29.01.2025 - 12.06.2025}

View file

@ -0,0 +1,69 @@
\documentclass[
11pt,
ngerman,
toc=listof, % Abbildungsverzeichnis sowie Tabellenverzeichnis in das Inhaltsverzeichnis aufnehmen
toc=bibliography, % Literaturverzeichnis in das Inhaltsverzeichnis aufnehmen
footnotes=multiple, % Trennen von direkt aufeinander folgenden Fußnoten
parskip=half, % vertikalen Abstand zwischen Absätzen verwenden anstatt horizontale Einrückung von Folgeabsätzen
numbers=noendperiod % Den letzten Punkt nach einer Nummerierung entfernen (nach DIN 5008)
]{scrartcl}
\pdfminorversion=5 % erlaubt das Einfügen von pdf-Dateien bis Version 1.7, ohne eine Fehlermeldung zu werfen (keine Garantie für fehlerfreies Einbetten!)
\usepackage[utf8]{inputenc} % muss als erstes eingebunden werden, da Meta/Packages ggfs. Sonderzeichen enthalten
\input{Meta} % Metadaten zu diesem Dokument (Autor usw.)
\input{Allgemein/Packages} % verwendete Packages
\input{Allgemein/Seitenstil} % Definitionen zum Aussehen der Seiten
\input{Allgemein/Befehle} % eigene allgemeine Befehle, die z.B. die Arbeit mit LaTeX erleichtern
\input{Befehle} % eigene projektspezifische Befehle, z.B. Abkürzungen usw.
\begin{document}
\phantomsection
\thispagestyle{plain}
\pdfbookmark[1]{Deckblatt}{deckblatt}
\input{Deckblatt}
\cleardoublepage
% Preface --------------------------------------------------------------------
\phantomsection
\pagenumbering{Roman}
\pdfbookmark[1]{Inhaltsverzeichnis}{inhalt}
\tableofcontents % Compile multiple times (e.g., 2-3 times) to ensure the Table of Contents is generated correctly.
\cleardoublepage
\phantomsection
\listoffigures
\cleardoublepage
\phantomsection
\cleardoublepage
\phantomsection
\cleardoublepage
\newcommand{\abkvz}{Abkürzungsverzeichnis}
\renewcommand{\nomname}{\abkvz}
\section*{\abkvz}
\markboth{\abkvz}{\abkvz}
\addcontentsline{toc}{section}{\abkvz}
\input{Abkuerzungen}
\clearpage
% Inhalt ---------------------------------------------------------------------
\pagenumbering{arabic}
\input{Inhalt.tex}
% Literatur ------------------------------------------------------------------
\clearpage
\renewcommand{\refname}{Literaturverzeichnis}
\bibliography{Bibliographie}
\bibliographystyle{Allgemein/natdin} % DIN-Stil des Literaturverzeichnisses
% Anhang ---------------------------------------------------------------------
\clearpage
\appendix
\pagenumbering{Roman}
\input{Anhang}
\end{document}

View file

@ -0,0 +1,12 @@
# LaTeX-Vorlage zur Projektdokumentation für Fachinformatiker Anwendungsentwicklung
Die Vorlage umfasst neben dem Layout und den obligatorischen Elementen wie Deckblatt, Verzeichnissen und Literaturangaben insbesondere eine Vorstrukturierung der üblicherweise geforderten Inhalte einer Dokumentation zur betrieblichen Projektarbeit inklusive einiger Beispiele für wichtige Inhalte wie z.B. Kostenkalkulation und Amortisationsrechnung. Obwohl viele Inhalte der Vorlage speziell auf Anwendungsentwickler zugeschnitten sind, dürfte die Vorlage auch für die anderen IT-Berufe (Fachinformatiker Systemintegration, IT-Kaufleute usw.) interessant sein, da die Vorgaben hinsichtlich der Projektarbeit größtenteils übereinstimmen.
Mehr Informationen und eine Beispieldokumentation auf Basis dieser Vorlage gibt es hier: [Vorlage für die Projektdokumentation][fiaevorlage].
[fiaevorlage]: http://fiae.link/LaTeXVorlageFIAE "Vorlage für die Projektdokumentation"
# Lizenz
[![Creative Commons Lizenzvertrag](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-sa/4.0/)
LaTeX-Vorlage zur IHK-Projektdokumentation für Fachinformatiker Anwendungsentwicklung von [Stefan Macke](http://fiae.link/LaTeXVorlageFIAE) ist lizenziert unter einer [Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz](http://creativecommons.org/licenses/by-sa/4.0/).

View file

@ -0,0 +1,11 @@
% Table generated by Excel2LaTeX from sheet 'Kostenaufstellung'
\begin{tabular}{lrlr}
\rowcolor{heading}\textbf{Vorgang} & \textbf{Zeit} & \textbf{Kosten pro Stunde} & \textbf{Kosten} \\
Entwicklungskosten & 70 \mbox{h} & $\eur{10} + \eur{15} = \eur{25}$ & \eur{1750} \\
\rowcolor{odd}Fachgespräch & 3 \mbox{h} & $\eur{25} + \eur{15} = \eur{40}$ & \eur{120} \\
Abnahmetest & 1 \mbox{h} & $\eur{25} + \eur{15} = \eur{40}$ & \eur{40} \\
\rowcolor{odd}Anwenderschulung & 25 \mbox{h} & $\eur{25} + \eur{15} = \eur{40}$ & \eur{1000} \\
\hline
\hline
\rowcolor{heading}\textbf{} & \textbf{} & \textbf{} & \textbf{\eur{2910}} \\
\end{tabular}

View file

@ -0,0 +1,11 @@
% Table generated by Excel2LaTeX from sheet 'Nutzwert'
\begin{tabular}{llllll}
\rowcolor{heading}\textbf{Eigenschaft} & \textbf{Gewichtung} & \textbf{Akelos} & \textbf{CakePHP} & \textbf{Symfony} & \textbf{Eigenentwicklung} \\
\textbf{Dokumentation} & 5 & 4 & 3 & 5 & 0 \\
\rowcolor{odd}\textbf{Reenginierung} & 3 & 4 & 2 & 5 & 3 \\
\textbf{Generierung} & 3 & 5 & 5 & 5 & 2 \\
\rowcolor{odd}\textbf{Testfälle} & 2 & 3 & 2 & 3 & 3 \\
\textbf{Standardaufgaben} & 4 & 3 & 3 & 3 & 0 \\
\rowcolor{heading}\textbf{Gesamt:} & \textbf{17} & \textbf{65} & \textbf{52} & \textbf{73} & \textbf{21} \\
\rowcolor{odd}\textbf{Nutzwert:} & & \textbf{3,82} & \textbf{3,06} & \textbf{4,29} & \textbf{1,24}\\
\end{tabular}

View file

@ -0,0 +1,9 @@
\begin{tabular}{lllll}
\rowcolor{heading}\textbf{Vorgang} & \textbf{Anzahl pro Monat} & \textbf{Zeit alt} & \textbf{Zeit neu} & \textbf{Einsparung} \\
Fehleranalyse & 10 & 30 min & 10 min & 200 min \\
\rowcolor{odd}Einarbeitung Modulstruktur & 2 & 120 min & 30 min & 180 min \\
Import von Daten & 5 & 10 min & 3 min & 35 min \\
\hline
\rowcolor{heading}\textbf{Zeiteinsparung Gesamt pro Monat} & & & & \textbf{415 min} \\
\end{tabular}

View file

@ -0,0 +1,13 @@
% Table generated by Excel2LaTeX from sheet 'Zeitnachher'
\begin{tabular}{lrrr}
\rowcolor{heading}\textbf{Phase} & \textbf{Geplant} & \textbf{Tatsächlich} & \textbf{Differenz} \\
\textbf{Analysephase} & 6 h & 6 h & \\
\rowcolor{odd}\textbf{Entwurfsphase} & 14 h & 14 h & \\
\textbf{Implementierungsphase} & 37 h & 28 h & -9 h \\
\rowcolor{odd}\textbf{Abnahmetest der Fachabteilung} & 5 h & 5 h & \\
\textbf{Einführungsphase} & 1 h & 1 h & \\
\rowcolor{odd}\textbf{Erstellen der Dokumentation} & 8 h & 17 h & +9 h \\
\hline
\hline
\rowcolor{odd}\textbf{Gesamt} & 70 h & 70 h & \\
\end{tabular}

View file

@ -0,0 +1,48 @@
% Table generated by Excel2LaTeX from sheet 'ZeitplanungKomplett'
\begin{tabularx}{\textwidth}{Xrrr}
\rowcolor{heading}\textbf{Analysephase} & \textbf{} & \textbf{} & \textbf{6 h} \\
1. Analyse des Ist-Zustands & & 2 h & \\
\rowcolor{odd}2. \gqq{Make or buy}-Entscheidung und Wirtschaftlichkeitsanalyse & & 1 h & \\
3. Erstellen eines \gqq{Use-Case}-Diagramms & & 2 h & \\
\rowcolor{odd}4. Erstellen des Lastenhefts & & 1 h & \\
\rowcolor{heading}\textbf{Entwurfsphase} & \textbf{} & \textbf{} & \textbf{14 h} \\
1. UML-Komponentendiagramm erstellen & & 1 h & \\
\rowcolor{odd}2. Datenbankentwurf & & 1 h & \\
2.1. \ac{M2} Migration für Tabelle definieren & 1 h & & \\
\rowcolor{odd}3. Erstellen des Schnittstellen Konzeptes für \ac{IX} & & 4 h & \\
3.1. Erstellung Verbindung zur \ac{IX} \ac{API} & 1 h & & \\
\rowcolor{odd}3.2. Verarbeitung der \ac{JSON}-Daten & 1 h & & \\
3.3. Verarbeitung der Konfigurationsdatei der Anwendung & 2 h & & \\
\rowcolor{odd}4. Benutzeroberflächen entwerfen und abstimmen & & 3 h & \\
5. Erstellen des Schnittstellen Konzeptes für \ac{M2} & & 4 h & \\
\rowcolor{odd}5.1 Erstellung Schnittstelle für \ac{M2} Import Funktionen & & 2 h & \\
5.2 Erstellung Schnittstelle zur Verarbeitung der geholten \ac{IX} \ac{JSON}-Daten & & 2 h & \\
\rowcolor{heading}\textbf{Implementierungsphase} & \textbf{} & \textbf{} & \textbf{37 h} \\
1. Anlegen der Datenbank & & 4 h & \\
\rowcolor{odd}2. Einrichtung der Docker Umgebung zur lokalen Entwicklung & & 2 h & \\
3. Programmierung der \ac{PHP}-Module für die Funktionen & & 29 h & \\
\rowcolor{odd}3.1 Erstellung eines Client Moduls zur Abfrage der \ac{IX} \ac{API} per \ac{curl} Requests & 3 h & & \\
3.2. Import der Produktdaten aus \ac{JSON}-Dateien & 2 h & & \\
\rowcolor{odd}3.3. Import der Nutzerdaten aus \ac{JSON}-Dateien & 2 h & & \\
3.4. Aufbereitung (Mapping) der geholten Daten für \ac{M2} & 3 h & & \\
\rowcolor{odd}Einbindung der Konfigurationsdateien & 4 h & & \\
3.6. Import der aufbereiteten Daten von \ac{IX} zu \ac{M2} & 5 h & & \\
\rowcolor{odd}3.7. Einbindung der \ac{CRON}-Job Möglichkeit & 3 h & & \\
3.8. Abdeckung der Module mit Unit-Tests & 4 h & & \\
\rowcolor{odd}4. Umsetzung der \ac{CLI} Benutzeroberfläche & & 2 h & \\
\rowcolor{heading}\textbf{Abnahmetest der Fachabteilung} & \textbf{} & \textbf{} & \textbf{3 h} \\
1. Abnahmetest der \ac{NSD} Mitarbeiter & & 3 h & \\
\rowcolor{heading}\textbf{Einführungsphase} & \textbf{} & \textbf{} & \textbf{1 h} \\
1. Einführung/Benutzerschulung & & 1 h & \\
\rowcolor{heading}\textbf{Erstellen der Dokumentation} & \textbf{} & \textbf{} & \textbf{9 h} \\
1. Erstellen der Entwicklerdokumentation & & 2 h & \\
\rowcolor{odd}2. Erstellen der Projektdokumentation & & 7 h & \\
\rowcolor{heading}\textbf{Gesamt} & \textbf{} & \textbf{} & \textbf{70 h} \\
\end{tabularx}

View file

@ -0,0 +1,12 @@
% Table generated by Excel2LaTeX from sheet 'ZeitplanungKurz'
\begin{tabular}{lr}
\rowcolor{heading}\textbf{Projektphase} & \textbf{Geplante Zeit} \\
Analysephase & 6 h \\
\rowcolor{odd}Entwurfsphase & 14 h \\
Implementierungsphase & 37 h \\
\rowcolor{odd}Abnahmetest der Fachabteilung & 5 h \\
Erstellen der Dokumentation & 8 h \\
\hline
\hline
\rowcolor{odd}\textbf{Gesamt} & \textbf{70 h} \\
\end{tabular}

View file

@ -0,0 +1,97 @@
% !TEX root = Projektdokumentation.tex
\section*{Über diese Vorlage}
Diese \LaTeX-Vorlage wurde von Stefan Macke\footnote{Blog des Autors:
\url{http://fachinformatiker-anwendungsentwicklung.net}, Twitter:
\Eingabe{@StefanMacke}} als Grundlage für die Projektdokumentationen der Auszubildenden zum Fachinformatiker mit Fachrichtung
Anwendungsentwicklung bei der \AO entwickelt. Nichtsdestotrotz dürfte sie ebenso für die anderen IT-Berufe\footnote{\zB IT-Kaufleute, Fachinformatiker
mit Fachrichtung Systemintegration \usw} geeignet sein, da diese anhand der gleichen Verordnung bewertet werden.
Diese Vorlage enthält bereits eine Vorstrukturierung der möglichen Inhalte einer tatsächlichen Projektdokumentation, die auf Basis der
Erfahrungen im Rahmen der Prüfertätigkeit des Autors erstellt und unter Zuhilfenahme von \citet{Rohrer2011} abgerundet wurden.
Sämtliche verwendeten Abbildungen, Tabellen und Listings stammen von \citet{Grashorn2010}.
Download-Link für diese Vorlage: \url{http://fiae.link/LaTeXVorlageFIAE}
Auch verfügbar auf GitHub: \url{https://github.com/StefanMacke/latex-vorlage-fiae}
\subsection*{Lizenz}
\begin{center}
\includegraphicsKeepAspectRatio{CC-Logo.pdf}{0.3}
\end{center}
Dieses Werk steht unter einer Creative Commons Namensnennung - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz.
\footnote{\url{http://creativecommons.org/licenses/by-sa/4.0/}}
\begin{center}
\includegraphicsKeepAspectRatio{CC-Attribution.pdf}{0.07}
\includegraphicsKeepAspectRatio{CC-ShareAlike.pdf}{0.07}
\end{center}
\begin{description}
\item[Namensnennung] Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen.
\footnote{Die Namensnennung im \LaTeX-Quelltext mit Link auf \url{http://fiae.link/LaTeXVorlageFIAE} reicht hierfür aus.}
\item[Weitergabe unter gleichen Bedingungen] Wenn Sie das lizenzierte Werk \bzw den lizenzierten Inhalt bearbeiten
oder in anderer Weise erkennbar als Grundlage für eigenes Schaffen verwenden, dürfen Sie die daraufhin neu entstandenen
Werke \bzw Inhalte nur unter Verwendung von Lizenzbedingungen weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.
\end{description}
\subsection*{Inhalt der Projektdokumentation}
Grundsätzlich definiert die \citet[S.~1746]{Bundesgesetzblatt48}\footnote{Dieses
Dokument sowie alle weiteren hier genannten können unter
\url{http://fiae.link/LaTeXVorlageFIAEQuellen} heruntergeladen werden.} das Ziel der Projektdokumentation wie folgt:
\begin{quote}
"`Durch die Projektarbeit und deren Dokumentation soll der Prüfling belegen, daß er Arbeitsabläufe und Teilaufgaben zielorientiert unter
Beachtung wirtschaftlicher, technischer, organisatorischer und zeitlicher Vorgaben selbständig planen und kundengerecht umsetzen sowie
Dokumentationen kundengerecht anfertigen, zusammenstellen und modifizieren kann."'
\end{quote}
Und das \citet[S.~36]{BMBF2000} ergänzt:
\begin{quote}
"`Die Ausführung der Projektarbeit wird mit praxisbezogenen Unterlagen dokumentiert.
Der Prüfungsausschuss bewertet die Projektarbeit anhand der Dokumentation. Dabei
wird nicht das Ergebnis -- \zB ein lauffähiges Programm -- herangezogen, sondern
der Arbeitsprozess. Die Dokumentation ist keine wissenschaftliche Abhandlung,
sondern eine handlungsorientierte Darstellung des Projektablaufs mit
praxisbezogenen, d.h. betriebüblichen Unterlagen. Sie soll einen Umfang von
maximal 10 bis 15 DIN A 4-Seiten nicht überschreiten. Soweit erforderlich können in
einem Anhang \zB den Zusammenhang erläuternde Darstellungen beigefügt werden."'
\end{quote}
Außerdem werden dort die grundlegenden Inhalte der Projektdokumentation aufgelistet:
\begin{itemize}
\item Name und Ausbildungsberuf des Prüfungsteilnehmers
\item Angabe des Ausbildungsbetriebes
\item Thema der Projektarbeit
\item Falls erforderlich, Beschreibung/Konkretisierung des Auftrages
\item Umfassende Beschreibung der Prozessschritte und der erzielten Ergebnisse
\item Gegebenenfalls Veränderungen zum Projektantrag mit Begründung
\item Wenn für das Projekt erforderlich, ein Anhang mit praxisbezogenen Unterlagen und Dokumenten. Dieser Anhang sollte nicht
aufgebläht werden. Die angehängten Dokumente und Unterlagen sind auf das absolute Minimum zu beschränken.
\end{itemize}
In den folgenden Kapiteln werden diese geforderten Inhalte und sinnvolle Ergänzungen nun meist stichwortartig und \ggfs mit
Beispielen beschrieben. Nicht alle Kapitel müssen in jeder Dokumentation vorhanden sein. Handelt es sich \bspw um ein in sich
geschlossenes Projekt, kann das Kapitel~\ref{sec:Projektabgrenzung}: \nameref{sec:Projektabgrenzung} entfallen; arbeitet die
Anwendung nur mit \acs{XML}-Dateien, kann und muss keine Datenbank beschrieben werden \usw
\subsection*{Formale Vorgaben}
Die formalen Vorgaben zum Umfang und zur Gestaltung der Projektdokumentation können je nach IHK recht unterschiedlich sein.
Normalerweise sollte die zuständige IHK einen Leitfaden bereitstellen, in dem alle Formalien nachgelesen werden können,
wie \zB bei der \citet{MerkblattIHK}.
Als Richtwert verwende ich 15 Seiten für den reinen Inhalt. Also in dieser Vorlage alle Seiten, die arabisch nummeriert
sind (ohne das Literaturverzeichnis und die eidesstattliche Erklärung).
Große Abbildungen, Quelltexte, Tabellen \usw gehören in den Anhang, der 25 Seiten nicht überschreiten sollte.
Typographische Konventionen, Seitenränder \usw können in der Datei \Datei{Seitenstil.tex} beliebig angepasst werden.
\subsection*{Bewertungskriterien}
Die Bewertungskriterien für die Benotung der Projektdokumentation sind recht einheitlich und können leicht in Erfahrung
gebracht werden, \zB bei der \citet{BewertungsmatrikIHK}.
Grundsätzlich sollte die Projektdokumentation nach der Fertigstellung noch einmal im Hinblick auf diese Kriterien durchgeschaut werden.

View file

@ -0,0 +1,14 @@
% in dieser Datei wird das Aussehen der Zitate und des Literaturverzeichnisses definiert
\newcommand{\bibstyle@natdin}%
{\bibpunct{[}{]}{;}{a}{}{,~} % Quellenangaben in eckige Klammern fassen
% nach dieser Definition wird das label (dinatlabel) fett geschrieben, dann Zeilenumbruch;
% darunter der bibliographische Beleg
\gdef\NAT@biblabelnum##1{\textbf{##1}\\}}
\bibstyle@natdin
% Einzug der Belege nach der Einordnungsmarke
\setlength{\bibhang}{7mm}