Add configuration files and update project documentation

- Introduced .editorconfig for consistent coding styles across the project.
- Added .golangci.yml for Go linting configuration.
- Updated AGENTS.md to clarify project structure and components.
- Enhanced CONTRIBUTING.md with Makefile usage for common tasks.
- Updated Dockerfiles to use Go 1.24 and improved build instructions.
- Refined README.md and deployment documentation for clarity.
- Added testing documentation in testing.md for backend and frontend tests.
- Introduced Makefile for streamlined development commands and tasks.
This commit is contained in:
2026-03-01 01:51:47 +03:00
parent 0466ff3087
commit 6529d7370e
92 changed files with 13411 additions and 8438 deletions

View File

@@ -1,50 +1,52 @@
/**
* Elements should have unique field "id"
*/
export interface Identifiable {
id: number | string
}
export class UniqueList<T extends Identifiable> {
elements: Record<string, T> = {}
update(
dataList: T[],
addCallback?: (it: T) => void,
removeCallback?: (it: T) => void,
updateCallback?: (oldElement: T, newElement: T) => void
): void {
const elementsToAdd = dataList.filter((it) => this.elements[String(it.id)] === undefined)
const elementsToRemove: T[] = []
for (const id of Object.keys(this.elements)) {
if (dataList.find((up) => String(up.id) === id) === undefined) {
const el = this.elements[id]
if (el) elementsToRemove.push(el)
}
}
if (removeCallback) {
elementsToRemove.forEach((it) => removeCallback(it))
}
if (updateCallback) {
dataList.forEach((newElement) => {
const oldElement = this.elements[String(newElement.id)]
if (oldElement) {
updateCallback(oldElement, newElement)
}
})
}
if (addCallback) {
elementsToAdd.forEach((it) => addCallback(it))
}
elementsToRemove.forEach((it) => delete this.elements[String(it.id)])
elementsToAdd.forEach((it) => (this.elements[String(it.id)] = it))
}
getElements(): T[] {
return Object.values(this.elements)
}
byId(id: number | string): T | undefined {
return this.elements[String(id)]
}
export interface UniqueList<T extends Identifiable> {
elements: Record<string, T>
}
export function createUniqueList<T extends Identifiable>(): UniqueList<T> {
return { elements: {} }
}
export function uniqueListUpdate<T extends Identifiable>(
list: UniqueList<T>,
dataList: T[],
addCallback?: (it: T) => void,
removeCallback?: (it: T) => void,
updateCallback?: (oldElement: T, newElement: T) => void
): void {
const elementsToAdd = dataList.filter((it) => list.elements[String(it.id)] === undefined)
const elementsToRemove: T[] = []
for (const id of Object.keys(list.elements)) {
if (dataList.find((up) => String(up.id) === id) === undefined) {
const el = list.elements[id]
if (el) elementsToRemove.push(el)
}
}
if (removeCallback) {
elementsToRemove.forEach((it) => removeCallback(it))
}
if (updateCallback) {
dataList.forEach((newElement) => {
const oldElement = list.elements[String(newElement.id)]
if (oldElement) {
updateCallback(oldElement, newElement)
}
})
}
if (addCallback) {
elementsToAdd.forEach((it) => addCallback(it))
}
elementsToRemove.forEach((it) => delete list.elements[String(it.id)])
elementsToAdd.forEach((it) => (list.elements[String(it.id)] = it))
}
export function uniqueListGetElements<T extends Identifiable>(list: UniqueList<T>): T[] {
return Object.values(list.elements)
}
export function uniqueListById<T extends Identifiable>(list: UniqueList<T>, id: number | string): T | undefined {
return list.elements[String(id)]
}