final-hill / cathedral Goto Github PK
View Code? Open in Web Editor NEWRequirements Engineering
Home Page: https://cathedral.final-hill.com/
License: GNU Affero General Public License v3.0
Requirements Engineering
Home Page: https://cathedral.final-hill.com/
License: GNU Affero General Public License v3.0
"Obligations and limits imposed on the project and system by the environment" HORABA page 40-41
"[A]n environment property that may affect components, goals, behaviors, tasks or products" The Anatomy of Software Requirements
HORABK p. 110
create a separate tab.
Also replace the enumerated stakeholder categories with High/Low pickers
Implement storage versioning to support schema evolution.
This is dependent on determining the ultimate storage strategy.
If it remains JSON one approach is to utilize the package version and have the data layer do the mapping based on the versions
Interactions between the environment, Actors, and the system
<role>
, I want to <behavior>
, so as to <goal>
<role>
from Project<behavior>
from System<goal>
from GoalsContext, Situation, Mission/Objective, Expected Benefits
An Effect is an environment property affected by a System.
Update the DataTable to prevent duplicate field entries
The application is deployed to https://final-hill.com/cathedral/. It lists everything as a 404 as it assumes it will be deployed to root.
An Assumption is a property of an environment that may be assumed. They are not imposed by the environment. Example: Client Screen resolutions will be larger than 1024x768
Currently borked and not deploying
The overall structure of the system expressed by a list of major parts (Components)
As an SPA, when an update is deployed clients have a good chance of not being updated due to long running sessions.
The user interfaces and APIs for each Component
Currently the DataTable enforces uniqueness constraint on entries.
The Domain should probably enforce this instead. Research a way to accomplish this.
For consistency, the MiniCards and PEGSCards should have a hover effect like the other navigable elements
State what the System will NOT do.
Implement Goals -> Use Cases section
Describes the behaviors (functional and non-functional) of Components. What the system does
Component | Behavior Category | Name | Description |
---|---|---|---|
MyComp | (Non-)Functional | Foo | Foo Description |
Classification of behaviors, interfaces, and scenarios by degree of criticality
Currently routing requires a standalone table initialized in Application._initRouter()
:
this.#router = new Router([
['/', (await import('./pages/Home.mjs')).Home],
['/not-found', (await import('./pages/NotFound.mjs')).NotFound],
['/projects', (await import('./pages/projects/Projects.mjs')).Projects],
['/environments', (await import('./pages/environments/Environments.mjs')).Environments],
['/environments/new-entry', (await import('./pages/environments/NewEnvironment.mjs')).NewEnvironment],
['/environments/:slug', (await import('./pages/environments/Environment.mjs')).Environment],
['/environments/:slug/glossary', (await import('./pages/environments/Glossary.mjs')).Glossary],
['/goals', (await import('./pages/goals/Goals.mjs')).Goals],
['/goals/new-entry', (await import('./pages/goals/NewGoals.mjs')).NewGoals],
['/goals/:slug', (await import('./pages/goals/Goal.mjs')).Goal],
['/goals/:slug/rationale', (await import('./pages/goals/Rationale.mjs')).Rationale],
['/goals/:slug/functionality', (await import('./pages/goals/Functionality.mjs')).Functionality],
['/goals/:slug/stakeholders', (await import('./pages/goals/Stakeholders.mjs')).Stakeholders],
['/goals/:slug/use-cases', (await import('./pages/goals/UseCases.mjs')).UseCases],
['/goals/:slug/limitations', (await import('./pages/goals/Limitations.mjs')).Limitations],
]);
this.#router.addEventListener('route', this);
Navigating to a page is accomplished via self.navigation.navigate(pathname)
A problem is that if a route changes, there is no error or warning of usage sites needing to change (Stringly typed)
Additionally, the parameters of the routes currently have to be parsed by subtypes of Page
such as in SlugPage
:
class SlugPage extends Page {
// /parent/:slug/foo
#slug = new URL(location.href, document.location.origin).pathname.split('/')[2];
constructor(properties: Properties<SlugPage>, children: (string | Element)[]) {
super(properties, children);
// ...
}
get slug() {
return this.#slug;
}
}
Routing should be integrated into the Page
class and initiating a route should accomplished via a method call on the page object itself instead of via self.navigate. Additionally, route parameters should be automatically available.
Rendering is still a bit awkward. The Template Method pattern approach causes problems with private field access which leads to verbose workarounds in certain cases
One approach, to avoid redundancy, would be to reify code comments into the class for the running application to access
Remove license headers from files.
With a LICENSE file in place this is sufficient. the header becomes redundant and introduces a maintenance burden for the year.
For some reason the .required::after
class is not being applied. Is this due to some bug with the shadow DOM or is it a bug with the CSSOM insertRule
method?
The framework has become more trouble than it's worth.
Build and deploy to github pages for now
The project currently utilizes the Navigation API to intercept navigation events and handle them
As of 2023-11-01, the Navigation API is still experimental and supported
by only Chromium-based browsers (~73% coverage as of January 2024)
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
https://developer.chrome.com/docs/web-platform/navigation-api/
https://caniuse.com/mdn-api_navigation
Types are polyfilled via dom-navigation package
Once the feature is fully adopted by major browsers, remove the polyfill
Currently all the mappers have the following form:
export interface FooJson extends BaseJson {
...props
}
export default class FooToJsonMapper extends BaseToJsonMapper {
override mapFrom(target: FooJson): Foo {
const version = target.serializationVersion ?? '{undefined}';
if (version.startsWith('0.3.'))
return new Foo(target);
//... additional versions
throw new Error(`Unsupported serialization version: ${version}`);
}
override mapTo(source: Foo): FooJson {
return {
...super.mapTo(source),
// ..additionalProps
};
}
}
Most repositories are of the form:
export default class FooRepository extends BaseRepository<Foo> {
constructor() { super('foo', new FooToJsonMapper(pkg.version)); }
}
There is also a LocalStorageRepository
specialized for the storage type:
export class LocalStorageRepository<E extends Entity> extends Repository<E> {
constructor(readonly storageKey: string, mapper: Mapper<E, EntityJson>) {
super(mapper);
}
get storage(): Storage {
return localStorage;
}
get(id: E['id']): Promise<E | undefined> { ... }
getAll(filter: (entity: E) => boolean = _ => true): Promise<E[]> { ... }
add(item: E): Promise<void> { ... }
clear(): Promise<void> { ... }
update(item: E): Promise<void> { ... }
delete(id: E['id']): Promise<void> { ... }
}
Note the storage
member which was defined to support unit testing:
const fakeStorage: Storage = new DomStorage(null, { strict: true });
class TestLocalStorageRepository<F extends Foo> extends LocalStorageRepository<F> {
override get storage() {
return fakeStorage;
}
}
This smells and has significant duplication. This needs to be done better
The SPA does not support direct navigation or reloads in deep links. Enable the Service Worker to support this use case
"A list of elements of the environment that may affect or be affected by the System and Project. Includes external systems to be interfaced with." HORBA page 40-41.
Clean Architecture needs to be followed more closely by leveraging use cases. Currently none are defined
Add eslint to the project
syncing data may become more complicated with a SQL database though. How can CRDTs be utilized?
Introduce Solution concept and move PEGS under it:
Convert the application to a PWA
Add unit testing to the project. Use the native Node test runner
Implement the Goals Functionality overview.
This includes high level behaviors only
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.