HN user

antoineleclair

112 karma
Posts4
Comments23
View on HN

We used CGI to add support for extensions in Disco (https://disco.cloud/).

It's so simple and it can run anything, and it was also relatively easy to have the CGI script run inside a Docker container provided by the extension.

In other words, it's so flexible that it means the extension developers would be able to use any language they want and wouldn't have to learn much about Disco.

I would probably not push to use it to serve big production sites, but I definitely think there's still a place for CGI.

In case anyone is curious, it's happening mostly here: https://github.com/letsdiscodev/disco-daemon/blob/main/disco...

It's not super simple, but here's how we did it for a long time:

All of your income that's not invested for retirement goes to a joint account, every 1st of the month. From that joint account, you then move the money to many different accounts and/or prepaid credit cards: - Day to day expenses, like groceries. - "Irregularities": municipal taxes, school taxes, things that don't happen every month, like car inspection, veterinary, vacation expenses. You add everything in a spreadsheet that you keep, and divide by 12. Add some padding. - Home improvements, aka "IKEA" account. Fixed amount every month. If it's a good that you buy to add you our home (coffee machine, chair, curtain, etc.), that's the account. If it's a consumable (gas for the car), use "day to day expenses". - Individual accounts: each one of you have an account that you decide what to do with. Buying clothes, hobby, etc. aka "I'm an adult, I do what I want". - Kids: There's always something to buy. Clothes, etc. - Automatic payments are taken from the main joint account, but you could also have another account if it makes it easier.

This method can get confusing and you may need to move money from one account to another one when the wrong card was used. But the main advantage is that it automatically budgets for you. You see the amount remaining for the month for everything. Otherwise, you may think that you still have plenty of money to spend on the grocery, so you buy a nice coffee machine, and then the mortgage and car payments happen and you're left with nothing for the rest of the month to do the grocery.

The main goals we had when using this method were to never use a credit card (and lose track of how much money we have), and also accommodate for the discrepancy in our revenues at the time.

Transactions can fail because they conflict with other transactions happening at the same time. It's not an application bug. It's real life transactions happening on a production system. It's normal for that to happen all the time. The app can retry, etc., but it should be expected to happen. Having to deal with distributed transactions is not something easy. Especially when they're part of many different systems. For example, you'd have to wait until the transaction commits successfully before setting the value in the cache, which makes it hard to read. Also, life in general happens. Compute a value, cache it, save things to the database, make API calls, and then a network error happens cancelling everything that you've just done. Having code that handles this kind of possibility is relatively hard to write/read.

For projects where I know the team will remain small (less than let's say 15 developers), I usually push to keep the architecture as simple as possible.

I've used something similar in the past, but kept the expiration code in the app code (Python) instead of using "fancy" Postgres features, like stored procedures. It's much easier to maintain since most developers will know how to read and maintain the Python code, that's also commited to the git repository.

Also, instead of using basic INSERT statements, you can "upsert".

INSERT INTO cache_items (key, created, updated, key, expires, value) VALUES (...) ON CONFLICT ON CONSTRAINT pk_cache_items DO UPDATE SET updated = ..., key = ..., expires = ..., value = ...;

And since you have control over the table, you can customize it however you want. Like adding categories of cache that you can invalidate all at once, etc.

Postgres is also pretty good at key/values.

In other words, I agree that using Postgres for things like caching, key/values, and even maybe message queue, can make sense, until it doesn't. When it doesn't make sense anymore, it's usually easy to migrate that one thing off of Postgres and keep the rest there.

Also, one benefit that's not often talked about is the complexity of distributed transactions when you have many systems.

Let's say you compute a value inside a transaction, cache it in Redis, and then the transaction fails. The cached valued is wrong. If everything is inside of Postgres, the cached value will also not be commited. One less thing to worry about.

I must admit it looks oddly similar. We did not see it on Coda site before using it. Not sure of the provenance (I will ask my designer).

As smackfu noted, the water drops are not exactly the same. But obviously, since it's very similar, we'll change it. It's very accidental and far from intentionnal.

I know, you're right. The original texts were written in French and then translated by someone else to English. We certainly have work left to be done in that area.

I decided to post it on HN anyway to get feedback ASAP.

Thanks for the example. The original (French) question is more like "Do you keep the documents?". I'll have this fixed.

I must say I'm not the legal expert in this project. I am a developer.

One of the co-founders is a lawyer by profession. I just noticed him with your interrogation.

From my understanding (again, I'm not speaking as the legal expert), what we do in case of a dispute regarding the legality of the signature process is providing a legal expert that will explain the process and why it's legal. We are not paying for a lawyer to defend the case in court.

You make it sound like it's totally insecure. Look at all the alternatives, and I am pretty sure we are the more secure.

Most still use a fax, which is incredibly insecure (how can you be sure who signed?). Other online solutions either use simple email reply or a hand-written signature.

Just to clarify the process, once you uploaded your file and chose the signatories, Signsquid sends a link to each signatory. Each one of them has its own unique link. Then, the sender (you), gain access to the list of codes assigned to each signatory. Again, each one of them as one unique code. You have to call them by phone to tell them the code.

If someone wanted to "hack" the process, he would have to gain access to the inbox of the user and also fake his voice over the phone.

You certainly have good points.

We try to be different than DocuSign, EchoSign, etc. with the process: no hand-written signature, a secure combination of unique link and unique code, no online contract editing.

I can't speak for SignNow.com, but on our side (Signsquid), we decided to ditch completely the hand-written signature, in favor of a better thought process.

We use a combination of a unique link, sent by email, and a unique secret code, told by phone, for each signatory. This way, we can be sure the good person signed.

Also, we decided to not enter the contract redaction process. You simply upload the pdf that will be signed.

Once the contract is signed, a page that contains the audit trail (who signed and when) is appended.

I've been practicing Wing Chun for 5 years now, and I must say it's probably the martial art that would suit a programmer mind the best.

Very logic, geometric.

It's a lot like C. Not so many basic "constructs" (no "batteries included"), but you can combine the basics to do powerful stuff.