improve: readme and configs
This commit is contained in:
@@ -1,56 +0,0 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Project Structure & Module Organization
|
||||
|
||||
This repository is an Angular 21 SSR application. Main app code lives in `src/`,
|
||||
with standalone components under `src/app/` such as `home/`, `footer/`, and
|
||||
`imprint/`. Shared constants are kept in `src/global.ts`. Component tests sit
|
||||
next to their source files as `*.spec.ts`. Automation and project maintenance
|
||||
scripts live in `scripts/`. Generated build output goes to `dist/` and should
|
||||
not be edited manually.
|
||||
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
- `npm run dev`: generate static assets, then start the Angular dev server.
|
||||
- `npm run build`: generate assets, create a production build, then copy static
|
||||
root files.
|
||||
- `npm run test`: run unit tests with Karma/Jasmine.
|
||||
- `npm run lint`: run the base ESLint config and the type-aware TypeScript
|
||||
config.
|
||||
- `npm run format:check`: verify Prettier formatting without changing files.
|
||||
- `npm run check`: full CI-style verification (`build`, `lint`, formatting,
|
||||
version, and text checks).
|
||||
- `npm run fix`: apply the local autofix workflow, including version placeholder
|
||||
reset, lint fixes, text cleanup, and Prettier.
|
||||
|
||||
## Coding Style & Naming Conventions
|
||||
|
||||
Follow `.editorconfig`: UTF-8, spaces, 2-space indentation, final newline, and
|
||||
trimmed trailing whitespace. Use Prettier for formatting and ESLint for code
|
||||
quality. Keep Angular file naming consistent: `feature.component.ts`,
|
||||
`feature.component.html`, and `feature.component.spec.ts`. Prefer PascalCase for
|
||||
classes and interfaces, camelCase for members, and keep scripts in CommonJS
|
||||
format as `*.cjs`.
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
The project uses Jasmine with Karma via `ng test`. Place tests beside the
|
||||
implementation file and keep names aligned with the component or module under
|
||||
test. Run `npm run test` for unit tests and `npm run check` before opening a PR.
|
||||
No explicit coverage gate is configured, so contributors should add focused
|
||||
tests for changed behavior.
|
||||
|
||||
## Commit & Pull Request Guidelines
|
||||
|
||||
Recent history mixes short imperative messages (`Update src/global.ts`) with
|
||||
lightweight conventional commits (`feat: pre-render routes and restore scroll`).
|
||||
Prefer concise, imperative commit subjects and include a scope or prefix when it
|
||||
adds clarity. PRs should summarize the user-visible change, mention any config
|
||||
or script updates, link related issues, and include screenshots for UI changes.
|
||||
|
||||
## Configuration Tips
|
||||
|
||||
Use the placeholder version workflow intentionally: `version:check` expects
|
||||
`YYDDDhhmm+GIT_HASH`, while build pipelines may resolve it through the scripts
|
||||
in `scripts/version.cjs`. Keep `package.json` and `package-lock.json` in sync,
|
||||
and avoid committing manual edits to generated files in `dist/`.
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||

|
||||
|
||||
## 👂 Languages/Framework/Packages:
|
||||
## 👂 Languages / Framework / Packages
|
||||
|
||||
- Angular v21
|
||||
- Angular v21 (with SSR)
|
||||
- TypeScript
|
||||
- SCSS
|
||||
- Angular Material
|
||||
- FontAwesome
|
||||
|
||||
## 💻 Development
|
||||
|
||||
@@ -21,18 +23,12 @@ npm run dev
|
||||
### Building
|
||||
|
||||
```bash
|
||||
npm run buildDevelopment
|
||||
```
|
||||
|
||||
or for Production Build
|
||||
|
||||
```bash
|
||||
npm run buildProduction
|
||||
npm run build
|
||||
```
|
||||
|
||||
This will compile your project and store the build artifacts in the `dist/`
|
||||
directory. By default, the production build optimizes your application for
|
||||
performance and speed.
|
||||
directory. The production build optimizes your application for performance and
|
||||
speed.
|
||||
|
||||
### Start compiled Project
|
||||
|
||||
@@ -40,28 +36,32 @@ performance and speed.
|
||||
npm run start
|
||||
```
|
||||
|
||||
## Running unit tests
|
||||
## 🔍 Code Quality
|
||||
|
||||
### Lint & Format check
|
||||
|
||||
```bash
|
||||
npm run check
|
||||
```
|
||||
|
||||
### Auto-fix lint & format issues
|
||||
|
||||
```bash
|
||||
npm run fix
|
||||
```
|
||||
|
||||
## 🧪 Running Unit Tests
|
||||
|
||||
To execute unit tests with the [Karma](https://karma-runner.github.io) test
|
||||
runner, use the following command:
|
||||
|
||||
```bash
|
||||
nom run test
|
||||
npm run test
|
||||
```
|
||||
|
||||
## Update Packages/Libraries
|
||||
|
||||
```bash
|
||||
npm run updatePackageVersions
|
||||
```
|
||||
|
||||
## 📋 Credits:
|
||||
|
||||
~ made by [**FrauJulian**](https://fraujulian.xyz/).
|
||||
|
||||
## 🤝 Enjoy?
|
||||
|
||||
Give it a star ⭐ on
|
||||
[github](https://github.com/FrauJulian/discord-audio-stream)!
|
||||
~ made by [**FrauJulian**](https://fraujulian.xyz/). Give it a star ⭐ on
|
||||
[GitHub](https://github.com/FrauJulian/Personal-Portfolio-Website)!
|
||||
|
||||
### Greetings from Austria! ⛰️
|
||||
|
||||
@@ -50,6 +50,8 @@ const config = [
|
||||
|
||||
/* Base */
|
||||
'no-debugger': 'warn',
|
||||
'no-var': 'error',
|
||||
'prefer-const': ['error', { destructuring: 'all' }],
|
||||
|
||||
/* TypeScript */
|
||||
'unused-imports/no-unused-imports': 'warn',
|
||||
|
||||
@@ -14,11 +14,16 @@ const typeAwareLayer = {
|
||||
'@typescript-eslint': require('@typescript-eslint/eslint-plugin'),
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-floating-promises': 'warn',
|
||||
'@typescript-eslint/no-misused-promises': ['warn', { checksVoidReturn: false }],
|
||||
'@typescript-eslint/no-unsafe-assignment': 'warn',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'warn',
|
||||
'@typescript-eslint/no-unsafe-argument': 'warn',
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
'@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }],
|
||||
'@typescript-eslint/no-unsafe-assignment': 'error',
|
||||
'@typescript-eslint/no-unsafe-member-access': 'error',
|
||||
'@typescript-eslint/no-unsafe-argument': 'error',
|
||||
'@typescript-eslint/no-unsafe-return': 'error',
|
||||
'@typescript-eslint/no-unsafe-call': 'error',
|
||||
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
||||
'@typescript-eslint/prefer-nullish-coalescing': 'warn',
|
||||
'@typescript-eslint/prefer-optional-chain': 'warn',
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
+21
-21
@@ -20,7 +20,7 @@ function writeJson(location, value) {
|
||||
}
|
||||
|
||||
function getSelectedMode() {
|
||||
let selectedModes = process.argv.slice(2).filter((value) => MODES.has(value));
|
||||
const selectedModes = process.argv.slice(2).filter((value) => MODES.has(value));
|
||||
|
||||
if (selectedModes.length !== 1) {
|
||||
throw new Error('Use exactly one mode: --set, --ensure, --check or --place.');
|
||||
@@ -30,7 +30,7 @@ function getSelectedMode() {
|
||||
}
|
||||
|
||||
function getVersionParts(version) {
|
||||
let parts = String(version).split('.');
|
||||
const parts = String(version).split('.');
|
||||
|
||||
if (parts.length < 3) {
|
||||
throw new Error(`Version "${version}" does not follow the expected major.minor.build format.`);
|
||||
@@ -40,12 +40,12 @@ function getVersionParts(version) {
|
||||
}
|
||||
|
||||
function getVersionPrefix(version) {
|
||||
let [major, minor] = getVersionParts(version);
|
||||
const [major, minor] = getVersionParts(version);
|
||||
return `${major}.${minor}.`;
|
||||
}
|
||||
|
||||
function getBuildPart(version) {
|
||||
let [, , buildPart] = getVersionParts(version);
|
||||
const [, , buildPart] = getVersionParts(version);
|
||||
return buildPart;
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ function hasPlaceholderVersion(version) {
|
||||
}
|
||||
|
||||
function hasResolvedVersion(version) {
|
||||
let buildPart = getBuildPart(version);
|
||||
const buildPart = getBuildPart(version);
|
||||
return buildPart !== VERSION_PLACEHOLDER && RESOLVED_BUILD_PATTERN.test(buildPart);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ function getExplicitVersion() {
|
||||
}
|
||||
|
||||
function getGitHash() {
|
||||
let explicitHash = process.env.BUILD_GIT_HASH?.trim() || process.env.GITHUB_SHA?.trim();
|
||||
const explicitHash = process.env.BUILD_GIT_HASH?.trim() || process.env.GITHUB_SHA?.trim();
|
||||
|
||||
if (explicitHash) {
|
||||
return explicitHash.slice(0, 7);
|
||||
@@ -81,18 +81,18 @@ function getGitHash() {
|
||||
}
|
||||
|
||||
function getBuildNumber() {
|
||||
let now = new Date();
|
||||
let year = String(now.getFullYear()).slice(-2);
|
||||
let startOfYear = new Date(now.getFullYear(), 0, 1);
|
||||
let dayOfYear = Math.floor((now - startOfYear) / (1000 * 60 * 60 * 24)) + 1;
|
||||
let hours = String(now.getHours()).padStart(2, '0');
|
||||
let minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
const now = new Date();
|
||||
const year = String(now.getFullYear()).slice(-2);
|
||||
const startOfYear = new Date(now.getFullYear(), 0, 1);
|
||||
const dayOfYear = Math.floor((now - startOfYear) / (1000 * 60 * 60 * 24)) + 1;
|
||||
const hours = String(now.getHours()).padStart(2, '0');
|
||||
const minutes = String(now.getMinutes()).padStart(2, '0');
|
||||
|
||||
return `${year}${String(dayOfYear).padStart(3, '0')}${hours}${minutes}`;
|
||||
}
|
||||
|
||||
function resolveVersion(currentVersion) {
|
||||
let explicitVersion = getExplicitVersion();
|
||||
const explicitVersion = getExplicitVersion();
|
||||
|
||||
if (explicitVersion) {
|
||||
return explicitVersion;
|
||||
@@ -102,7 +102,7 @@ function resolveVersion(currentVersion) {
|
||||
}
|
||||
|
||||
function isAlreadyEnsured(currentVersion) {
|
||||
let explicitVersion = getExplicitVersion();
|
||||
const explicitVersion = getExplicitVersion();
|
||||
|
||||
if (explicitVersion) {
|
||||
return currentVersion === explicitVersion;
|
||||
@@ -112,7 +112,7 @@ function isAlreadyEnsured(currentVersion) {
|
||||
}
|
||||
|
||||
function writeResolvedVersion(resolvedVersion) {
|
||||
let packageJson = readJson(PACKAGE_JSON_PATH);
|
||||
const packageJson = readJson(PACKAGE_JSON_PATH);
|
||||
packageJson.version = resolvedVersion;
|
||||
writeJson(PACKAGE_JSON_PATH, packageJson);
|
||||
|
||||
@@ -120,7 +120,7 @@ function writeResolvedVersion(resolvedVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
let packageLock = readJson(PACKAGE_LOCK_PATH);
|
||||
const packageLock = readJson(PACKAGE_LOCK_PATH);
|
||||
packageLock.version = resolvedVersion;
|
||||
|
||||
if (packageLock.packages && packageLock.packages['']) {
|
||||
@@ -161,7 +161,7 @@ function runEnsure(currentVersion) {
|
||||
}
|
||||
|
||||
function runSet(currentVersion) {
|
||||
let resolvedVersion = resolveVersion(currentVersion);
|
||||
const resolvedVersion = resolveVersion(currentVersion);
|
||||
writeResolvedVersion(resolvedVersion);
|
||||
console.log(`Version set to: ${resolvedVersion}`);
|
||||
}
|
||||
@@ -172,10 +172,10 @@ function runSetPlace() {
|
||||
}
|
||||
|
||||
try {
|
||||
let selectedMode = getSelectedMode();
|
||||
let packageJson = readJson(PACKAGE_JSON_PATH);
|
||||
let packageVersion = String(packageJson.version);
|
||||
let currentVersion = String(packageJson.currentVersion);
|
||||
const selectedMode = getSelectedMode();
|
||||
const packageJson = readJson(PACKAGE_JSON_PATH);
|
||||
const packageVersion = String(packageJson.version);
|
||||
const currentVersion = String(packageJson.currentVersion);
|
||||
|
||||
switch (selectedMode) {
|
||||
case '--check':
|
||||
|
||||
@@ -95,10 +95,12 @@
|
||||
<div class="story-grid">
|
||||
<div class="story-copy">
|
||||
<p>
|
||||
My name is {{ global.firstname }}, though most people call me Julie. I’m{{ age }}and based in Austria. A large part of my day happens on the move — usually on trains, going between meetings, offices, and time with my family.
|
||||
My name is {{ global.firstname }}, though most people call me Julie. I’m{{ age }}and based in Austria. A large part of my day
|
||||
happens on the move — usually on trains, going between meetings, offices, and time with my family.
|
||||
</p>
|
||||
<p>
|
||||
I work with modern web technologies and on business-critical systems. I don’t care much for unnecessary complexity — I focus on clear, stable solutions that actually hold up in day-to-day use and deliver real value.
|
||||
I work with modern web technologies and on business-critical systems. I don’t care much for unnecessary complexity — I focus on
|
||||
clear, stable solutions that actually hold up in day-to-day use and deliver real value.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -111,13 +113,16 @@
|
||||
@if (isLongBioMounted) {
|
||||
<div class="detail-panel" [class.detail-panel-enter]="isLongBioShown" [class.detail-panel-leave]="!isLongBioShown">
|
||||
<p>
|
||||
What really interests me is modern code — well-structured, maintainable, and built with performance in mind. No unnecessary bloat, just clean, readable solutions that reliably work under real-world conditions… in theory 😁
|
||||
What really interests me is modern code — well-structured, maintainable, and built with performance in mind. No unnecessary
|
||||
bloat, just clean, readable solutions that reliably work under real-world conditions… in theory 😁
|
||||
</p>
|
||||
<p>
|
||||
Outside of software, my main hobby is scuba diving. The silence underwater and the focus on the present moment keep pulling me back into Austria’s dark, cold lakes.
|
||||
Outside of software, my main hobby is scuba diving. The silence underwater and the focus on the present moment keep pulling me
|
||||
back into Austria’s dark, cold lakes.
|
||||
</p>
|
||||
<p>
|
||||
Right now, I mainly work for SobIT GmbH in Vienna, alongside freelance projects for companies, organizations, and private clients. No gimmicks — just software that does what it’s supposed to do, built properly.
|
||||
Right now, I mainly work for SobIT GmbH in Vienna, alongside freelance projects for companies, organizations, and private
|
||||
clients. No gimmicks — just software that does what it’s supposed to do, built properly.
|
||||
</p>
|
||||
<button class="inline-link inline-link-button" type="button" (click)="scrollToContactLinks()">Get in touch</button>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
<p class="eyebrow">Legal</p>
|
||||
<h1>Imprint & Privacy</h1>
|
||||
<p class="hero-intro legal-intro">
|
||||
Legal information for this website under Austrian law, including privacy information for websites operated by {{ global.firstname }} {{ global.lastname }}
|
||||
Legal information for this website under Austrian law, including privacy information for websites operated by
|
||||
{{ global.firstname }} {{ global.lastname }}
|
||||
(Lechner Systems).
|
||||
</p>
|
||||
</div>
|
||||
|
||||
+4
-1
@@ -3,7 +3,10 @@
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="description" content="Full-stack developer building reliable, high-performance systems and clean, maintainable code. Focused on practical solutions that actually hold up in production.">
|
||||
<meta
|
||||
name="description"
|
||||
content="Full-stack developer building reliable, high-performance systems and clean, maintainable code. Focused on practical solutions that actually hold up in production."
|
||||
/>
|
||||
<base href="/" />
|
||||
|
||||
<link rel="icon" type="image/webp" sizes="128x128" href="assets/optimized/portrait/me-128.webp" />
|
||||
|
||||
Reference in New Issue
Block a user