Remove unused defaultCustomerId/Name config; add README
This commit is contained in:
parent
e9506b400f
commit
061869384a
3 changed files with 92 additions and 7 deletions
90
README.md
Normal file
90
README.md
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
# Asset Browser
|
||||||
|
|
||||||
|
A self-hosted web application for browsing and managing assets pulled from Syncro MSP. Provides role-based access for technicians and clients, barcode label generation, and a label queue for batch printing.
|
||||||
|
|
||||||
|
Built by Carmichael Computing.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- Node.js 22 or higher
|
||||||
|
- PM2 (`npm install -g pm2`)
|
||||||
|
- A Syncro MSP account with API access
|
||||||
|
- A reverse proxy (nginx recommended) for production
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
**1. Clone the repository and install dependencies**
|
||||||
|
|
||||||
|
```
|
||||||
|
git clone https://git.farmtowntech.com/setonc/asset_browser.git
|
||||||
|
cd asset_browser
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Configure environment**
|
||||||
|
|
||||||
|
```
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `.env` and fill in the following:
|
||||||
|
|
||||||
|
- `SESSION_SECRET` — a long random string, generate one with:
|
||||||
|
```
|
||||||
|
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
|
||||||
|
```
|
||||||
|
- `SYNCRO_BASE_URL` — your Syncro API base URL, e.g. `https://yoursubdomain.syncromsp.com/api/v1`
|
||||||
|
- `SYNCRO_API_KEY` — your Syncro API key
|
||||||
|
|
||||||
|
**3. Configure the client**
|
||||||
|
|
||||||
|
Edit `public/config.js` and update the `syncro` block with your Syncro subdomain and base URL.
|
||||||
|
|
||||||
|
**4. Update the PM2 config**
|
||||||
|
|
||||||
|
Edit `ecosystem.config.js` and set `cwd` to the absolute path of the installation directory, and update `name` if desired.
|
||||||
|
|
||||||
|
**5. Create the first admin user**
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run create-user
|
||||||
|
```
|
||||||
|
|
||||||
|
Follow the prompts. Choose the `superduperadmin` role for full access.
|
||||||
|
|
||||||
|
**6. Start the server**
|
||||||
|
|
||||||
|
```
|
||||||
|
pm2 start ecosystem.config.js
|
||||||
|
pm2 save
|
||||||
|
```
|
||||||
|
|
||||||
|
The server listens on port 3000 by default. Point your reverse proxy at it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## User Management
|
||||||
|
|
||||||
|
The `create-user` script handles all user management from the command line:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run create-user # create a new user (interactive)
|
||||||
|
npm run create-user list # list all users
|
||||||
|
npm run create-user deactivate <id> # deactivate a user
|
||||||
|
npm run create-user reset <id> # reset a user's password
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roles
|
||||||
|
|
||||||
|
| Role | Access |
|
||||||
|
|------------------|---------------------------------------------|
|
||||||
|
| superduperadmin | Full access including server management |
|
||||||
|
| admin | User management and all standard features |
|
||||||
|
| tech | Asset browsing, label printing |
|
||||||
|
| client | Read-only access scoped to their company |
|
||||||
|
|
@ -1,7 +1,4 @@
|
||||||
import { apiRequest } from './utils.js';
|
import { apiRequest } from './utils.js';
|
||||||
import CONFIG from '../config.js';
|
|
||||||
|
|
||||||
const { defaultCustomerId } = CONFIG.app;
|
|
||||||
|
|
||||||
// ── Assets ───────────────────────────────────────────────────────────────────
|
// ── Assets ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -28,7 +25,7 @@ export async function updateAsset(id, fields, customerId) {
|
||||||
// ── Contacts ─────────────────────────────────────────────────────────────────
|
// ── Contacts ─────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// Fetches via Node.js server cache — server handles pagination internally
|
// Fetches via Node.js server cache — server handles pagination internally
|
||||||
export async function getContacts(customerId = defaultCustomerId) {
|
export async function getContacts(customerId) {
|
||||||
const res = await fetch(`/api/contacts/${customerId}`, {
|
const res = await fetch(`/api/contacts/${customerId}`, {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
headers: { Accept: 'application/json' },
|
headers: { Accept: 'application/json' },
|
||||||
|
|
@ -63,7 +60,7 @@ export async function getCustomerAssets(customerId) {
|
||||||
|
|
||||||
// ── Tickets ──────────────────────────────────────────────────────────────────
|
// ── Tickets ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
export async function getTickets(customerId = defaultCustomerId) {
|
export async function getTickets(customerId) {
|
||||||
const data = await apiRequest('GET', '/tickets', null, {
|
const data = await apiRequest('GET', '/tickets', null, {
|
||||||
customer_id: customerId,
|
customer_id: customerId,
|
||||||
per_page: 100, // fetch enough to filter client-side by contact
|
per_page: 100, // fetch enough to filter client-side by contact
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ const CONFIG = {
|
||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
idleTimeout: 180000, // ms before returning to scan mode (3 minutes)
|
idleTimeout: 180000, // ms before returning to scan mode (3 minutes)
|
||||||
defaultCustomerId: 33332476,
|
|
||||||
defaultCustomerName: 'Prime Home Health',
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue