Skip to content

Commit bacd2be

Browse files
committed
init
1 parent 002ac33 commit bacd2be

File tree

139 files changed

+2926
-4
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+2926
-4
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
.pos
3+
tmp

README.md

+89-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,89 @@
1-
# pos-module-chat
1+
# Chat Module
2+
3+
This module serves as a starting point for adding real time chat to your application. Before using the module for the first time, we recommend reading the official platformOS documentation on [WebSockets](https://documentation.platformos.com/use-cases/using-websockets) and on [Example Application](#example-application).
4+
5+
This module follows the [platformOS DevKit best practices](https://documentation.staging.oregon.platform-os.com/developer-guide/modules/platformos-modules) and includes the [core module](https://github.com/Platform-OS/pos-module-core) as a dependency, enabling you to implement patterns such as [Commands](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#commands--business-logic) and [Events](https://github.com/Platform-OS/pos-module-core?tab=readme-ov-file#events). It also includes the [user module](https://github.com/Platform-OS/pos-module-user) and [profile module](https://github.com/Platform-OS/pos-module-profile) as a dependency.
6+
7+
For more information,
8+
- read the documentation about the [built-in User table](https://documentation.platformos.com/developer-guide/users/user),
9+
- learn about [how platformOS manages sessions](https://documentation.platformos.com/developer-guide/users/session),
10+
- and gain a high-level overview of [authentication strategies in platformOS](https://documentation.platformos.com/developer-guide/users/authentication).
11+
12+
## Installation
13+
14+
The platformOS Chat Module is available on the [Partner Portal Modules Marketplace](https://partners.platformos.com/marketplace/pos_modules/152).
15+
16+
### Prerequisites
17+
18+
Before installing the module, ensure that you have [pos-cli](https://github.com/mdyd-dev/pos-cli#overview) installed. This tool is essential for managing and deploying platformOS projects.
19+
20+
The platformOS Chat Module is fully compatible with [platformOS Check](https://github.com/Platform-OS/platformos-lsp#platformos-check----a-linter-for-platformos), a linter and language server that supports any IDE with Language Server Protocol (LSP) integration. For Visual Studio Code users, you can enhance your development experience by installing the [VSCode platformOS Check Extension](https://marketplace.visualstudio.com/items?itemName=platformOS.platformos-check-vscode).
21+
22+
### Installation Steps
23+
24+
1. **Navigate to your project directory** where you want to install the Chat Module.
25+
26+
2. **Run the installation command**:
27+
28+
```bash
29+
pos-cli modules install chat
30+
```
31+
32+
This command installs the Chat Module along with its dependencies (such as [pos-module-core](https://github.com/Platform-OS/pos-module-core)) and updates or creates the `app/pos-modules.json` file in your project directory to track module configurations.
33+
34+
### Setup
35+
36+
1. **Install the module** using the [pos-cli](https://github.com/Platform-OS/pos-cli).
37+
38+
2. If you haven't done it already, follow the instructions to setup [pos-module-user-](https://github.com/Platform-OS/pos-module-user?tab=readme-ov-file#setup). During this process, you will create an overwrite of the permissions file `app/modules/user/public/lib/queries/role_permissions/permissions.liquid`
39+
40+
3. Overwrite default views that you would like to customize by following the guide on [overwriting a module file](https://documentation.platformos.com/developer-guide/modules/modules#overwritting-a-module-file). This allows you to add functionality based on your project requirements. At a minimum, you should overwrite the [permissions file](modules/user/public/lib/queries/role_permissions/permissions.liquid), where you will configure [RBAC authorization](#rbac-authorization) roles and permissions for your application - add `chat.inbox` permission to the role(s) that you would like to have access to the chat available at `/inbox`. In our example, the `inbox.chat` permission was added to `authenticated` role, meaning all signed in users have access to the chat. Snippet to create an overwrite to copy-paste into your terminal:
41+
42+
```
43+
mkdir -p app/modules/user/public/lib/queries/role_permissions
44+
cp modules/user/public/lib/queries/role_permissions/permissions.liquid app/modules/user/public/lib/queries/role_permissions/permissions.liquid
45+
```
46+
47+
### Managing Module Files
48+
49+
The default behavior of modules is that **the files are never deleted**. It is assumed that developers might not have access to all of the files, and thanks to this feature, they can still overwrite some of the module's files without breaking them. Since the User Module is fully public, it is recommended to delete files on deployment. To do this, ensure your `app/config.yml` includes the User Module and its dependencies in the list `modules_that_allow_delete_on_deploy`:
50+
51+
``` yaml
52+
modules_that_allow_delete_on_deploy:
53+
- core
54+
- user
55+
- profile
56+
- chat
57+
```
58+
59+
## Example application
60+
61+
We recommend creating a [new Instance](https://partners.platformos.com/instances/new) and deploying this module as an application to get a better understanding of the basics and the functionality this module provides. When you install the module using `pos-cli modules install chat`, only the contents of the `modules/chat` will be available in your project. The `app` directory serves as an example of how you could incorporate the Chat Module into your application. When analyzing the code in the `app` directory, pay attention to the following files:
62+
63+
* ** `app/config.yml`** and **`app/user.yml`**: These files are defined according to the [Setup](#setup) instructions.
64+
* ** `app/modules/user/public/lib/queries/role_permissions/permissions.liquid`**: Demonstrates how to configure permissions in your application by [overwriting a module file](https://documentation.platformos.com/developer-guide/modules/modules#overwriting-a-module-file).
65+
66+
## Functionality provided by the chat module:
67+
68+
Once the module is installed and you have completed the [setup](#setup), you will immediately gain access to the new endpoints created by this module. For example, you can navigate to `/inbox` for the chat window.
69+
70+
- [x] **[Inbox](#inbox)**:
71+
72+
TODO (Upcoming Features)
73+
74+
75+
### Inbox
76+
77+
Inbox
78+
79+
#### Endpoints for the registration
80+
81+
The table below outlines the [resourceful routes](https://documentation.platformos.com/developer-guide/modules/platformos-modules#resourceful-route-naming-convention) provided for registration functionality:
82+
83+
| HTTP method | slug | page file path | description
84+
|---|---|---|---|---|
85+
| GET | /inbox | `modules/chat/public/views/pages/inbox.liquid` | Renders a chat |
86+
87+
#### CRUD commands
88+
89+
...
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{% parse_json data %}
2+
{
3+
{% if context.constants.USER_DEFAULT_ROLE != blank %}
4+
"{{ context.constants.USER_DEFAULT_ROLE }}": [],
5+
{% endif %}
6+
"anonymous": ["sessions.create", "users.register"],
7+
"authenticated": ["sessions.destroy", "chat.inbox"]
8+
}
9+
{% endparse_json %}
10+
11+
{% return data %}

modules/chat/public/views/pages/inbox.html.liquid

+7-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@ slug: inbox
33
---
44

55
{% liquid
6+
function current_user = 'modules/user/queries/user/current'
7+
8+
# platformos-check-disable ConvertIncludeToRenderl, UnreachableCode
9+
include 'modules/user/helpers/can_do_or_unauthorized', requester: current_user, do: 'chat.inbox', return_url: '/'
10+
# platformos-check-enable ConvertIncludeToRender, UnreachableCode
11+
12+
function current_profile = 'modules/profile/queries/profiles/find', user_id: current_user.id, id: null, uuid: null, first_name: null, last_name: null
613
function current_profile = 'modules/community/helpers/current_profile', user_id: context.current_user.id
7-
include 'modules/community/helpers/profile_present_or_redirect', profile: current_profile
814

915
function record = 'modules/chat/lib/queries/records/find_by_uuid', uuid: context.params['to_uuid']
1016
assign object = null | hash_merge: to_id: record.id, conversation_id: context.params['conversation_id']

modules/chat/template-values.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
"name": "Pos Module Chat",
33
"machine_name": "chat",
44
"type": "module",
5-
"version": "0.0.9",
5+
"version": "1.0.0",
66
"dependencies": {
77
"components": "^1.1.3",
88
"core": "^1.0.0",
9-
"profile": "^1.0.0"
9+
"profile": "^1.0.0",
10+
"user": "^1.0.0"
1011
}
1112
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
mutation (
2+
$uuid: String!
3+
$user_id: String!,
4+
$first_name: String,
5+
$last_name: String
6+
$name: String
7+
$email: String
8+
$c__names: String
9+
) {
10+
record: record_create(
11+
record: {
12+
table: "modules/profile/profile"
13+
properties: [
14+
{ name: "user_id", value: $user_id }
15+
{ name: "first_name", value: $first_name }
16+
{ name: "last_name", value: $last_name }
17+
{ name: "uuid", value: $uuid }
18+
{ name: "name", value: $name }
19+
{ name: "email", value: $email }
20+
{ name: "c__names", value: $c__names }
21+
]
22+
}
23+
) {
24+
id
25+
created_at
26+
type: table
27+
properties
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
mutation delete_profile($id: ID!) {
2+
record: record_delete(
3+
table: "modules/profile/profile"
4+
id: $id
5+
){ id }
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
query (
2+
$page: Int = 1
3+
$limit: Int = 20
4+
$first_name: String
5+
$last_name: String
6+
$email: String
7+
$emails: [String!]
8+
$id: ID
9+
$ids: [ID!]
10+
$not_ids: [ID!]
11+
$uuid: String
12+
$user_id: String
13+
$sort: RecordsSortInput = { created_at: { order: DESC } }
14+
$query: String
15+
) {
16+
records(
17+
page: $page
18+
per_page: $limit
19+
filter: {
20+
id: { value: $id, value_in: $ids, not_value_in: $not_ids }
21+
table: { value: "modules/profile/profile" }
22+
properties: [
23+
{ name: "uuid", value: $uuid }
24+
{ name: "first_name", value: $first_name }
25+
{ name: "last_name", value: $last_name }
26+
{ name: "user_id", value: $user_id }
27+
{ name: "email", value: $email, value_in: $emails }
28+
{ name: "c__names", contains: $query }
29+
]
30+
}
31+
sort: [$sort]
32+
) {
33+
total_entries
34+
total_pages
35+
has_previous_page
36+
has_next_page
37+
results {
38+
id
39+
created_at
40+
type: table
41+
42+
properties
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mutation profiles_update(
2+
$id: ID!
3+
$name: String
4+
$first_name: String
5+
$last_name: String
6+
$email: String
7+
$c__names: String
8+
) {
9+
record: record_update(
10+
id: $id
11+
record: {
12+
table: "modules/profile/profile"
13+
properties: [
14+
{ name: "name", value: $name }
15+
{ name: "first_name", value: $first_name }
16+
{ name: "last_name", value: $last_name }
17+
{ name: "email", value: $email }
18+
{ name: "c__names", value: $c__names }
19+
]
20+
}
21+
) {
22+
id
23+
created_at
24+
type: table
25+
26+
properties
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% liquid
2+
function object = 'modules/profile/commands/profiles/create/build', object: object, name: null
3+
function object = 'modules/profile/commands/profiles/create/check', object: object
4+
if object.valid
5+
function object = 'modules/core/commands/execute', mutation_name: 'modules/profile/profiles/create', object: object
6+
assign object = object | hash_merge: object.properties
7+
endif
8+
return object
9+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% liquid
2+
function tokenized_names = 'modules/profile/commands/profiles/tokenize_names', object: object
3+
assign uuid_new = '' | uuid
4+
assign uuid = object.uuid | default: uuid_new
5+
assign name = object.first_name | append: ' ' | append: object.last_name
6+
7+
assign data = null | hash_merge: first_name: object.first_name, last_name: object.last_name, user_id: object.user_id, email: object.email, uuid: uuid, name: name, c__names: tokenized_names
8+
9+
return data
10+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{% liquid
2+
assign c = '{ "errors": {}, "valid": true }' | parse_json
3+
4+
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'user_id', key: 'validation.blank'
5+
function table = 'modules/profile/helpers/table_name'
6+
function c = 'modules/core/validations/uniqueness', c: c, object: object, field_name: 'user_id', table: table, key: 'validation.user_already_has_profile', scope_name: null, exclude_name: null
7+
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'uuid', key: 'validation.blank'
8+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'name', maximum: 80, allow_blank: null
9+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'first_name', maximum: 40, allow_blank: null
10+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'last_name', maximum: 40, allow_blank: null
11+
12+
assign object = object | hash_merge: c
13+
14+
return object
15+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% liquid
2+
function profile_module = 'modules/core/queries/variable/get', name: 'PROFILE_MODULE', default: 'modules/profile', type: null
3+
assign function_name = profile_module | append: '/commands/profiles/create'
4+
function profile = function_name, object: object
5+
return profile
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% liquid
2+
function object = 'modules/profile/commands/profiles/create/build', object: object, name: null
3+
function object = 'modules/profile/commands/profiles/create/check', object: object
4+
5+
return object
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% liquid
2+
function profile_module = 'modules/core/queries/variable/get', name: 'PROFILE_MODULE', default: 'modules/profile', type: null
3+
assign function_name = profile_module | append: '/commands/profiles/create_validate'
4+
function profile = function_name, object: object
5+
return profile
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% liquid
2+
function object = 'modules/profile/commands/profiles/delete/build', object: object
3+
function object = 'modules/profile/commands/profiles/delete/check', object: object
4+
if object.valid
5+
function object = 'modules/core/commands/execute', mutation_name: 'modules/profile/profiles/delete', object: object
6+
endif
7+
return object
8+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% liquid
2+
assign data = null | hash_merge: id: object.id
3+
4+
return data
5+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{% liquid
2+
assign c = '{ "errors": {}, "valid": true }' | parse_json
3+
4+
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'id', key: 'validation.blank'
5+
6+
assign object = object | hash_merge: c
7+
8+
return object
9+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% liquid
2+
function profile_module = 'modules/core/queries/variable/get', name: 'PROFILE_MODULE', default: 'modules/profile', type: null
3+
assign function_name = profile_module | append: '/commands/profiles/delete'
4+
function profile = function_name, object: object
5+
return profile
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{% liquid
2+
assign tokenized_names = '[]' | parse_json | array_add: object.email | array_add: object.first_name | array_add: object.last_name | compact | uniq | join: ' ' | downcase
3+
return tokenized_names
4+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{% liquid
2+
function object = 'modules/profile/commands/profiles/update/build', object: object, profile: profile, name: null
3+
function object = 'modules/profile/commands/profiles/update/check', object: object
4+
5+
if object.valid
6+
function object = 'modules/core/commands/execute', mutation_name: 'modules/profile/profiles/update', object: object
7+
assign object = object | hash_merge: object.properties
8+
endif
9+
return object
10+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{% liquid
2+
function tokenized_names = 'modules/profile/commands/profiles/tokenize_names', object: object
3+
assign name = object.first_name | append: ' ' | append: object.last_name
4+
5+
assign data = null | hash_merge: id: profile.id, first_name: object.first_name, last_name: object.last_name, name: name, c__names: tokenized_names, email: object.email
6+
7+
return data
8+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{% liquid
2+
assign c = '{ "errors": {}, "valid": true }' | parse_json
3+
4+
function c = 'modules/core/validations/presence', c: c, object: object, field_name: 'id', key: 'validation.blank'
5+
function c = 'modules/core/validations/uniqueness', c: c, object: object, field_name: 'email', table: 'modules/profile/profile', scope_name: null, exclude_name: null
6+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'name', maximum: 80, allow_blank: null
7+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'first_name', maximum: 40, allow_blank: null
8+
function c = 'modules/core/validations/length', c: c, object: object, field_name: 'last_name', maximum: 40, allow_blank: null
9+
10+
11+
assign object = object | hash_merge: c
12+
13+
return object
14+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{% liquid
2+
function profile_module = 'modules/core/queries/variable/get', name: 'PROFILE_MODULE', default: 'modules/profile', type: null
3+
assign function_name = profile_module | append: '/commands/profiles/update'
4+
function profile = function_name, object: object, profile: profile
5+
return profile
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{%liquid
2+
assign first_name = current_profile.properties.first_name
3+
assign last_name = current_profile.properties.last_name
4+
assign slug = first_name | append: '-' | append: last_name | append: '-' | append: current_profile.id | slugify
5+
return slug
6+
%}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% liquid
2+
function profile_module = 'modules/core/queries/variable/get', name: 'PROFILE_MODULE', default: 'modules/profile', type: null
3+
4+
return profile_module | append: '/profile'
5+
%}

0 commit comments

Comments
 (0)