CHANGELOG.md showed only the five newest releases, so what was about to be released was only in CHANGELOG-big.md. changelog-short.mjs now puts the unreleased # Upcoming WeKan ® release first - its In short and a link to its full section - and the five newest releases below it; right after a release, when there is no Upcoming yet, none is invented. CLAUDE.md and AGENTS.md say what "update wekan changelog" means: find the commits not in the changelog yet, add an Upcoming section when a release was cut meanwhile, write the entries and the In short into CHANGELOG-big.md, run changelog-short.mjs, run the changelog tests, and commit both files. tests/changelogShort.test.cjs: Upcoming first, whole, above the releases, its link resolves, and no Upcoming appears after a release. Thanks to xet7 !
28 KiB
Where everything is
The sections below walk through the directories in detail. This table is the whole tree at a glance, because the detail is easy to get lost in - and because for years this page described four directories out of twenty and did not say so.
| Directory | What is in it |
|---|---|
| client/ | everything the browser runs: Blaze components, their styles, the client-side libraries |
| server/ | everything only the server runs: startup, publications, methods, the REST routes, lib/ |
| models/ | the collections, their schemas, helpers and mutations - shared by both, so a model must never import from server/ |
| imports/ | shared code that is neither a model nor a component: i18n, the reactive cache, the shared SimpleSchema, startup |
| packages/ | the Meteor packages WeKan maintains itself - the accounts integrations (CAS, LDAP, OIDC, Sandstorm), the lockout, markdown |
| config/ | the router and the accounts configuration |
| migrations/ | one file per database migration, run in order at startup |
| public/ | files served as-is: icons, fonts, the web app manifest |
| private/ | files the SERVER can read and the client cannot |
| tests/ | the suites - *.test.cjs run by tests/run-node-suites.cjs, plus the Playwright and e2e directories |
| docs/ | this documentation |
| releases/ | how a release is built and published - the bundle steps, the translations tooling, the CHANGELOG tooling |
| snap/, snap-src/, snap-base-debian/ | the snap package |
| sandstorm-src/ | the Sandstorm package |
| openapi/ | the REST API description, generated from the routes |
| meta/ | signatures, icons, screenshots, project description |
| old-CHANGELOG/ | the CHANGELOG's history, by year and by month, a busy month in parts (CHANGELOG-big.md holds the Status, the upcoming release and the newest releases that fit GitHub's 500 KiB Markdown limit; CHANGELOG.md only the In short of the upcoming release and the five newest) |
.tools/ |
NOT part of this repository: the companion repos and toolchains a build needs, ignored by git and by Meteor |
node_modules/, .meteor/, .build/, _build/ |
generated; never edited, never committed |
The two build directories are different things, and the names are close enough to be worth stating:
| what it is | |
|---|---|
.build/ |
the RELEASE bundle, from meteor build .build --directory. .build/bundle is what gets deployed, tested and packaged. |
_build/ |
rspack's compiled output, written by ANY Meteor compile — a dev run, a test run, a release build. Meteor reads the app's main modules from _build/main-prod/, so it is a HANDOFF, not a leftover. |
_build/ is gitignored but must not be added to .meteorignore — ignoring
it breaks the build outright, and that file explains why. Anything that walks
the repository should skip it: it holds a second, bundled copy of every source
file, so a tool that reads it finds every file twice and reports the bundler's
rewritten code as if it were source.
Two rules that the layout only implies:
models/is shared code. It is loaded on the client too, so a model that imports fromserver/breaks the client build. Server-only logic that a model needs lives behindMeteor.isServeror inserver/lib/.- A
.jadefile is not picked up by being on disk. Every template is imported by name fromclient/features/*.js, and a component.jsthat other components import must import its own.jade- seetests/clientBundleImports.test.cjsandtests/templateRegistration.test.cjs.
Routing
We're using FlowRouter client side router inside config/router.js. For accounts there is AccountsTemplates configured in config/accounts.js.
Client
public
Files in this directory are served by meteor as-is to the client. It hosts some (fav)icons and fonts.
svg-etc/manifest.json: goes into link rel="manifest" in the header of the generated page and is a Web App Manifest.
components
- activities:
- activities.jade:
activitiestemplate for the list of activities placed inside asidebar-content; usesboardActivitiesorcardActivitiesdepending onmode; XXX: does this mean that sidebar should be visible in board list mode? when does theboardactivity gets shown? - comments.jade:
commentFormtemplate used incard-details-canvasfor adding comments;
- activities.jade:
- boards:
- boardArchive.jade:
archivedBoardstemplate for the modal dialog showing the list of archived boards that might be restored; - boardBody.jade: top level template for presenting a board is
boardand, based on screen size and current state, it uses eithercardDetailsorboardBodytemplates;boardBodyis the one including thesidebar, eachlist,cardDetailsfor larger screens when a card is selected and theaddListFormfor adding a new list (also defined in this file); - boardHeader.jade:
boardHeaderBar,boardMenuPopup,boardVisibilityList,boardChangeVisibilityPopup,boardChangeWatchPopup,boardChangeColorPopup,createBoard,chooseBoardSource,boardChangeTitlePopup,archiveBoardPopup,outgoingWebhooksPopup; - boardsList.jade:
boardListandboardListHeaderBarfor the list of boards in the initial screen;
- boardArchive.jade:
- cards:
- attachments.jade:
cardAttachmentsPopup,previewClipboardImagePopup,previewAttachedImagePopup,attachmentDeletePopup,attachmentsGalery; - cardDate.jade:
editCardDateanddateBadgetemplates; - cardDetails.jade:
boardsAndListsis the usual layout for a board display withboardListsbeing used in sandstorm where each board is independent;cardDetails,editCardTitleForm,cardDetailsActionsPopup,moveCardPopup,copyCardPopup,cardMembersPopup,cardMorePopup,cardDeletePopup; - cardTime.jade:
editCardSpentTimeandtimeBadgetemplates; - checklists.jade:
checklists,checklistDetail,checklistDeleteDialog,addChecklistItemForm,editChecklistItemForm,checklistItems,itemDetail; - labels.jade:
formLabel,createLabelPopup,editLabelPopup,deleteLabelPopup,cardLabelsPopup; - minicard.jade: has the
minicardtemplate
- attachments.jade:
- forms: inlinedform.jade has the
inlinedFormtemplate; - import:
- import.jade:
importHeaderBar,import,importTextarea,importMapMembers,importMapMembersAddPopupare all templates used for importing Trello (via trelloMembersMapper.js) and Wekan (via wekanMembersMapper.js) boards;
- import.jade:
- lists:
- list.jade:
listis the simple, main template for lists; - listBody.jade:
listBody,addCardForm,autocompleteLabelLinetemplates; - listHeader.jade:
listHeader,editListTitleForm,listActionPopup,boardLists,listMorePopup,listDeletePopup,setWipLimitPopup,wipLimitErrorPopuptemplates;
- list.jade:
- main:
- editor.jade:
editorandviewertemplates; - header.jade:
headerandofflineWarningtemplates; if the user is connected we display a small "quick-access" top bar that list all starred boards with a link to go there (this is inspired by the Reddit "subreddit" bar); the first link goes to the boards page; - keyboardShortcuts.jade:
shortcutsHeaderBar,shortcutsModalTitle,keyboardShortcuts- all for the shortcuts that are presented when you press?re implemented inhere; - layouts.jade: has the template for head portion of the html page and other general purpose templates:
userFormsLayout,defaultLayout,notFound,message; - popup.tpl.jade: tpl files only define a single template so there's no need to wrap content in a template tag; the name of the template is the base name of the file (
popupin this case);
- editor.jade:
- settings:
- informationBody.jade: the
statisticstemplate — the Version pane of Admin Panel / Settings, five tables (Platform, OS, Meteor, Database, Node). There is noinformationtemplate any more: it is a pane rendered bysettingBody.jade, not a page; - invitationCode.jade:
invitationCodetemplate; - peopleBody.jade:
people,peopleGeneral,peopleRow,editUserPopup; - settingBody.jade:
setting,general,email,accountSettings,announcementSettings - settingHeader.jade:
settingHeaderBartemplate;
- informationBody.jade: the
- sidebar:
- sidebar.jade:
sidebar,homeSidebar,membersWidget,labelsWidget,memberPopup,removeMemberPopup,leaveBoardPopup,addMemberPopup,changePermissionsPopup - sidebarArchives.jade:
archivesSidebar - sidebarFilters.jade:
filterSidebar,multiselectionSidebar,disambiguateMultiLabelPopup,disambiguateMultiMemberPopup,moveSelectionPopup;
- sidebar.jade:
- users:
- userAvatar.jade:
userAvatar,userAvatarInitials,userPopup,memberName,changeAvatarPopup,cardMemberPopup - userHeader.jade:
headerUserBar,memberMenuPopup,editProfilePopup,editNotificationPopup,changePasswordPopup,changeLanguagePopup,changeSettingsPopup;
- userAvatar.jade:
features
client/features is the list of what the client
LOADS. One file per area - boards.js, cards.js, settings.js, main.js and
so on - each importing that area's .jade, then its .js, then its .css, and
client/imports.js imports them all. A component that is not named here is not
in the bundle, however finished it is: tests/templateRegistration.test.cjs
fails when a template is included by name and never imported.
config
- blazeHelpers.js: following Blaze helpers are registered here:
currentBoard(),currentCard(),getUser()andconcat(); - gecko-fix.js: removes deprecated
watchandunwatchfrom Firefox prior to version 58;
lib
- accessibility.js: define a set of DOM transformations that are specifically intended for blind screen readers;
- cssEvents.js: the
CSSEventsobject has methods that select the name of the event based on the specific transitions and animations; - pasteImage.js and dropImage.js: utility for pasting and dropping images on a web app; XXX: add comments; not same style as the rest of the code
- escapeActions.js: defines the behavior (mostly canceling current edit) for escape keyboard key;
- i18n.js: at startup we choose the language for the ui based on user profile or browser language;
- inlinedform.js: forms for editing a single field (like adding a card); XXX: comments in code suggest that a form that is not submitted will retain its value to prevent data loss using unsavedEdits.js;bug?; XXX: edit button to save and open;
- minicardLabelText.js: reads and writes the personal
Hide minicard label textsetting (the user's profile, or this browser when nobody is logged in), used by the minicard and byBoard Settings / Card's "Labels text" row; - sectionCaret.js: which way a collapsible section's caret points — down when open, and toward the text when closed, mirrored in right-to-left languages — shared by the card's sections and the board sidebar's
Activities; - keyboard.js: the shortcuts that are presented when you press
?re implemented inhere; - popup.js: defines
Popupclass for things likes electing a date; XXX: not a Blaze helper? - textComplete.js: extends jquery-textcomplete to integrate with the rest of the system (like escape actions, tab and enter key handling); XXX: deprecated?
- utils.js: various methods all over the place (resize, screen size, sort, capitalize, navigate to board and card);
- Blaze helpers:
- filter.js: registers
FilterBlaze helper to support filtering cards by labels and by members; - modal.js: registers
ModalBlaze helper to support showing modal windows like the one for archived boards; - multiSelection.js: registers
ModalBlaze helper to support multiple selection mode; - unsavedEdits.js: registers
getUnsavedValueandhasUnsavedValueBlaze helpers to preserve content entered in fields but not saved;
- filter.js: registers
Server
.js files in this directory are not available to the client.
The four directories that hold most of it:
-
server/lib - the server-only libraries the rest of it calls. The security log and the event-log fold that Admin Panel / Problems is built on, the login throttle and timing defence, the database problem classifier, the API usage counter, the recovery and migration helpers.
-
server/methods - Meteor methods that are not part of a model: the backups, the repairs, the reports the Admin Panel calls.
-
server/publications - what the client may subscribe to, and with which fields.
-
server/routes - the HTTP routes that are not the REST API: the avatar server, the attachment routes, the custom head assets. The REST API itself is registered by the models, in front of server/apiMiddleware.js - body parsing, the
WITH_APIgate, bearer-token authentication, and the usage counting behind Admin Panel / Problems / API. -
server/startup and the
00*.jsfiles at the top - what runs before anything else, in name order: the startup checks, waiting for the database, the retry-on-busy wrapper, the error handlers. -
statistics.js implements a Meteor server-only method for general-purpose information such as OS, memory, CPUs, PID of the process and so on.
-
migrations.js is where code that update sold databases to new schema is located. Anytime the schema of one of the collection changes in a non-backward compatible way a migration needs to be written in this file.
-
authentication.js add the
Authenticationobject to Meteor that provides methods for checking access rights. -
lib/utils.js defines some checks used by checklists.js** model. XXX: these methods are defined in server-only code by are used in models, which are visible by the client (in Checklists.allow)?
-
- notifications.js: defines the
Notificationsobject that supports Activities and holds a list of functions to call when itsnotify()method is called along with convenience methods to subscribe, unsubscribe and a way to filter recipients according to user settings for notification;- email.js: makes use of the notification system to send an email to a user;
- profile.js: stub; will allow associating notifications with user ids to be consumed by mobile apps;
- notifications.js: adds the
watch()Meteor server-only method that may watch boards, lists or cards using models/watchable.js; - outgoing.js: adds the
outgoingWebhooks()Meteor server-only method that can call external API XXX: I guess
- notifications.js: defines the
-
publications defines sets of records that are published by the server and how clients can subscribe to those:
- accountSettings.js: AccountSettings collection;
- activities.js: Activities collection filtered and paginated;
- announcements.js: Announcements collection;
- avatars.js: Avatars collection for current user;
- boards.js: Boards collection for current user, archived boards collection and individual board as a relation;
- cards.js: a Card by its id;
- people.js: Users collection;
- settings.js: Settings collection and, separately, the mail server;
- unsavedEdits.js: UnsavedEdits collection;
- users.js: provides a "mini-profile" for individual users and a way to check if current user is admin.
Models
The files in models directory mainly define collections; most of them have aldeed SimpleSchema for automatic validation of insert and update of collections. This is also where helpers, mutations, methods, hooks and bootstrap code is to be found. Server side code also implements json REST API.
models/lib is the other half of this directory, and by
file count the larger one: the PURE modules a model, the server and the client
all share - the event-log summary shape, the address classifier, the admin URLs
and menus, the shared table page, the lockout state, the map links. They are
plain CommonJS with no Meteor in them, which is what lets
tests/*.test.cjs run them under bare node and test a decision as arithmetic
rather than through a server.
Collections (mostly Mongo.Collection except as noted) are defined in:
- accountSettings.js;
- activities.js: does not have a SimpleSchema;
- announcements.js;
- attachments.js: file-system collection;
- avatars.js: file-system collection;
- boards.js;
- cardComments.js;
- cards.js;
- checklists.js;
- integrations.js;
- invitationCodes.js;
- lists.js;
- settings.js;
- unsavedEdits.js;
- users.js: extends the
Meteor.userscollection.
Other files:
- watchable.js: extends the schema, helpers and mutations of
Boards,ListsandCards. - export.js: has some code to support the REST API.
- import.js: implements
importBoard()method so that Trello (in trelloCreator.js) and Wekan (in wekanCreator.js) boards can be imported. XXX: Solid candidates for a directory of their own.
Tools
- Git:
- .git;
- .gitignore;
- Docker:
- docker-compose.yml: the compose file is a YAML file defining services, networks and volumes;
- Dockerfile;
- Snap:
- snapcraft.yaml: Snapcraft packages any app for every Linux desktop, server, cloud or device, and deliver updates directly;
- snap;
- snap-src;
- Sandstorm:
- sandstorm.js: Sandstorm specific code;
- sandstorm-pkgdef.capnp: used the meteor-spk tool to generate a sandstorm package;
- Node:
- package.json;
- node_modules
- app.json: is a manifest format for describing web apps (build requirements, environment variables, addons, and other information);
- app.env: environment variables;
- Meteor: is a full-stack JavaScript platform for developing modern web and mobile applications.
- Translation:
- Text editors:
- .vscode: Visual Studio Code Editor;
- .editorconfig: EditorConfig provides consistent coding styles between different editors and IDEs;
- .github: hosts the issues template;
- .eslintrc.json: ESLint configuration;
- .travis.yml: configuration for Travis CI;
- scalingo.json: Scalingo is a deploy solution;
Building, releasing and testing
- build.sh / build.bat - the menu
that installs dependencies, builds WeKan and runs the tests. Its Setup menu
builds either the release bundle (what a release publishes, minus the
.zip) or the development bundle (plain
meteor build). - releases/ - one script per step of a release, and the
same scripts the GitHub workflow runs, so a release can be reproduced locally:
- release-all.sh - the whole release, from
the CHANGELOG's
# Upcomingsection; takes no version number. - build-release-bundle.sh - the bundle a release publishes, for the machine it is run on.
- bundle-trim.mjs, prune-unreachable-npm.mjs, bundle-smoke-boot.sh - what a bundle carries, what it does not, and whether it starts at all.
- translations/ - the Transifex pull and the per-key merge that never overwrites a human translation.
- changelog-archive.mjs - moves
finished months out of
CHANGELOG-big.mdintoold-CHANGELOG/. - changelog-short.mjs - writes
CHANGELOG.md, the In short of the upcoming release and the five newest, fromCHANGELOG-big.md.
- release-all.sh - the whole release, from
the CHANGELOG's
- tests/ -
*.test.cjssuites run by run-node-suites.cjs (all of them, with every failure listed at the end), plus the Playwright browser tests and the e2e/import suites. Many of them READ THE SOURCE and pin a behaviour, which is what makes "and this mistake is nowhere else in the tree" checkable. - .github/workflows -
release-all.ymlis the release: the bundles for every platform, the Docker images, the snaps, and the GitHub Release they attach to.
Info
- meta: binary signatures, project description, icons, screenshots and, oui, a French change-log;
- CHANGELOG.md - the upcoming release and the five newest, in short, and CHANGELOG-big.md - every change, the upcoming release and the status;
- Contributing.md;
- LICENSE;
- README.md.
Contributions to this page
This page was contributed by TNick and
xet7 when WeKan was at commit
e2f768c,
and it described the tree as it was then for a long time afterwards: fourteen of
its links pointed at files that had moved or been deleted, and two thirds of the
repository - imports/, packages/, releases/, tests/, docs/,
migrations/, server/lib, server/methods, server/routes, models/lib,
client/features - was not mentioned at all.
Please add new files, fixes and updates directly to this page.
tests/docsLinksResolve.test.cjs fails when a link here points at something that
is not in the tree, which is what let the fourteen rot unnoticed: a
https://github.com/wekan/wekan/tree/main/... link looks fine in an editor and
404s only for the reader.